我在数据框中有两列和迄今为止
当我尝试添加新的列差异时,使用
查找两个日期之间的差异df['diff'] = df['todate'] - df['fromdate']
如果超过24小时,我会在几天内得到差异列。
2014-01-24 13:03:12.050000,2014-01-26 23:41:21.870000,"2 days, 10:38:09.820000"
2014-01-27 11:57:18.240000,2014-01-27 15:38:22.540000,03:41:04.300000
2014-01-23 10:07:47.660000,2014-01-23 18:50:41.420000,08:42:53.760000
如何仅在小时和分钟内转换结果,忽略天数甚至秒数。
答案 0 :(得分:72)
Pandas时间戳差异返回datetime.timedelta对象。这可以通过使用* as_type *方法轻松转换为小时,如此
import pandas
df = pandas.DataFrame(columns=['to','fr','ans'])
df.to = [pandas.Timestamp('2014-01-24 13:03:12.050000'), pandas.Timestamp('2014-01-27 11:57:18.240000'), pandas.Timestamp('2014-01-23 10:07:47.660000')]
df.fr = [pandas.Timestamp('2014-01-26 23:41:21.870000'), pandas.Timestamp('2014-01-27 15:38:22.540000'), pandas.Timestamp('2014-01-23 18:50:41.420000')]
(df.fr-df.to).astype('timedelta64[h]')
屈服,
0 58
1 3
2 8
dtype: float64
答案 1 :(得分:27)
由于上面的.astype()
解决方案对我不起作用,这让我感到疯狂。但我发现了另一种方式。没有时间或其他任何东西,但可能会为其他人工作:
t1 = pd.to_datetime('1/1/2015 01:00')
t2 = pd.to_datetime('1/1/2015 03:30')
print pd.Timedelta(t2 - t1).seconds / 3600.0
...如果你想要几个小时。或者:
print pd.Timedelta(t2 - t1).seconds / 60.0
...如果你想要分钟。
答案 2 :(得分:5)
days + hours
。 不包括分钟。 hh:mm
或x hours y minutes
,则需要进行其他计算和字符串格式设置。timedelta
数学来获得总小时数或总分钟数,并且比使用.astype('timedelta64[h]')
更快timedelta
objects:请参阅支持的操作。import pandas as pd
# test data from OP, with values already in a datetime format
data = {'to_date': [pd.Timestamp('2014-01-24 13:03:12.050000'), pd.Timestamp('2014-01-27 11:57:18.240000'), pd.Timestamp('2014-01-23 10:07:47.660000')],
'from_date': [pd.Timestamp('2014-01-26 23:41:21.870000'), pd.Timestamp('2014-01-27 15:38:22.540000'), pd.Timestamp('2014-01-23 18:50:41.420000')]}
# test dataframe; the columns must be in a datetime format; use pandas.to_datetime if needed
df = pd.DataFrame(data)
# add a timedelta column if wanted. It's added here for information only
# df['time_delta_with_sub'] = df.from_date.sub(df.to_date) # also works
df['time_delta'] = (df.from_date - df.to_date)
# create a column with timedelta as total hours, as a float type
df['tot_hour_diff'] = (df.from_date - df.to_date) / pd.Timedelta(hours=1)
# create a colume with timedelta as total minutes, as a float type
df['tot_mins_diff'] = (df.from_date - df.to_date) / pd.Timedelta(minutes=1)
# display(df)
to_date from_date time_delta tot_hour_diff tot_mins_diff
0 2014-01-24 13:03:12.050 2014-01-26 23:41:21.870 2 days 10:38:09.820000 58.636061 3518.163667
1 2014-01-27 11:57:18.240 2014-01-27 15:38:22.540 0 days 03:41:04.300000 3.684528 221.071667
2 2014-01-23 10:07:47.660 2014-01-23 18:50:41.420 0 days 08:42:53.760000 8.714933 522.896000
.total_seconds()
中的播客中有一个注释项是在核心开发人员休假期间添加并合并的,因此不会获得批准。
.total_xx
方法的原因。# convert the entire timedelta to seconds
# this is the same as td / timedelta(seconds=1)
(df.from_date - df.to_date).dt.total_seconds()
[out]:
0 211089.82
1 13264.30
2 31373.76
dtype: float64
# get the number of days
(df.from_date - df.to_date).dt.days
[out]:
0 2
1 0
2 0
dtype: int64
# get the seconds for hours + minutes + seconds, but not days
# note the difference from total_seconds
(df.from_date - df.to_date).dt.seconds
[out]:
0 38289
1 13264
2 31373
dtype: int64
dateutil
的维护者:
(df.from_date - df.to_date) / pd.Timedelta(hours=1)
(df.from_date - df.to_date).dt.total_seconds() / 3600
dateutil
模块提供了对标准datetime
模块的强大扩展。%%timeit
测试import pandas as pd
# dataframe with 2M rows
data = {'to_date': [pd.Timestamp('2014-01-24 13:03:12.050000'), pd.Timestamp('2014-01-27 11:57:18.240000')], 'from_date': [pd.Timestamp('2014-01-26 23:41:21.870000'), pd.Timestamp('2014-01-27 15:38:22.540000')]}
df = pd.DataFrame(data)
df = pd.concat([df] * 1000000).reset_index(drop=True)
%%timeit
(df.from_date - df.to_date) / pd.Timedelta(hours=1)
[out]:
43.1 ms ± 1.05 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
(df.from_date - df.to_date).astype('timedelta64[h]')
[out]:
59.8 ms ± 1.29 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)