将以秒为单位的时间戳转换为hh:mm:ss格式的时间

4

我有一个包含秒数的df,其中一个column。我想将它们转换为hh:mmhh:mm:ss

如果时间超过标准24小时制,我仍然希望显示为hh:mm:ss,而不是'n' days hh:mm:ss

举个例子:

import pandas as pd
import numpy as np
import datetime

ts1 = ['21000', np.nan, '40000', np.nan, '49000', '100000']
ts2 = [0, 2, 'yy', 3, 'yy', 'yy']
ts3 = [0, 2, np.nan, 3, 4, np.nan]
d =  {'X': ts1, 'Y': ts2, 'Z': ts3}
df = pd.DataFrame(data=d)

输出:

        X   Y    Z
0   21000   0  0.0
1     NaN   2  2.0
2   40000  yy  NaN
3     NaN   3  3.0
4   49000  yy  4.0
5  100000  yy  NaN

我可以使用以下方法在单个字符串上执行此操作:
t = str(datetime.timedelta(seconds=21000))

输出 t:

5:50:00    

但是如何将同一个函数应用到整个列呢?
#t_col = str(datetime.timedelta(seconds=df['ts1']))

预期输出:

          X   Y    Z
0   5:50:00   0  0.0
1       NaN   2  2.0
2  11:06:40  yy  NaN
3       Nan   3  3.0
4  13:36:40  yy  4.0
5  27:46:40  yy  NaN
2个回答

0

更为逐步的方法

首先,让我们创建新的列并摆脱烦人的NaN值。

In [156]: df['new_column'] = df.X.fillna(0)

In [157]: df
Out[157]:
       X   Y    Z new_column
0  21000   0  0.0      21000
1    NaN   2  2.0          0
2  40000  yy  NaN      40000
3    NaN   3  3.0          0
4  49000  yy  4.0      49000
5  80000  yy  NaN      80000

接下来,我们可以通过使用基于您编写的代码的lambda函数来处理创建增量。请注意,我们必须将新列的值转换为int以适应timedeltaseconds参数。

In [158]: df['new_column'] = df.apply(lambda x: datetime.timedelta(seconds=int(x['new_column'])), axis=1)

In [159]: df
Out[159]:
       X   Y    Z new_column
0  21000   0  0.0   05:50:00
1    NaN   2  2.0   00:00:00
2  40000  yy  NaN   11:06:40
3    NaN   3  3.0   00:00:00
4  49000  yy  4.0   13:36:40
5  80000  yy  NaN   22:13:20

使用一行代码

在之前的基础上,我们需要消除NaN,然后将整个系列首先转换为int,然后再转换为timedelta

In [173]: df['td'] = pd.to_timedelta(pd.to_numeric(df.X.fillna(0)), unit='s')

In [174]: df
Out[174]:
       X   Y    Z new_column       td
0  21000   0  0.0   05:50:00 05:50:00
1    NaN   2  2.0   00:00:00 00:00:00
2  40000  yy  NaN   11:06:40 11:06:40
3    NaN   3  3.0   00:00:00 00:00:00
4  49000  yy  4.0   13:36:40 13:36:40
5  80000  yy  NaN   22:13:20 22:13:20

这种方法应该会更快,因为apply的速度相当

根据您的评论,为了与NaN保持一致,您可以使用这个。

df['td'] = df.apply(lambda x: x['td'] if x['X'] is not np.NaN else None, axis=1)

另外,我们能否在转换之前或之后删除00:00:00? - user9394674
@PeterJames123,您正在重新定义问题。这已经超出了您最初要求的范围。 - aydow
不是吗?NaN 是可以接受的。现在我需要把它们删除掉。如果时间实际上是 00:00:00,我将无法区分。 - user9394674
我指的是你删除的评论,你在那里要求我编写超过24小时的代码。你的第一个问题在范围内,我已经更新了我的回答来回答它。 - aydow
抱歉,我可以添加那些内容。没关系,我只需要使用.replace方法就可以了。 - user9394674

0

使用pandas.to_timedelta,然后通过一些混乱的字符串格式化将天数转换为小时:

def formatter(x):
    x = str(x)
    return str(int(x[-8:-6])+int(x.split('days')[0])*24).zfill(2) + x[-6:]

df['TD'] = pd.to_timedelta(df['X'].fillna(0).astype(int), unit='s')\
             .apply(formatter)

print(df)

        X   Y    Z        TD
0   21000   0  0.0  05:50:00
1     NaN   2  2.0  00:00:00
2   40000  yy  NaN  11:06:40
3     NaN   3  3.0  00:00:00
4   49000  yy  4.0  13:36:40
5  100000  yy  NaN  27:46:40

1
很好运行 @jpp - user9394674

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接