从 TimeDelta 到 Pandas 中的浮动天数
Posted
技术标签:
【中文标题】从 TimeDelta 到 Pandas 中的浮动天数【英文标题】:From TimeDelta to float days in Pandas 【发布时间】:2016-05-31 21:15:36 【问题描述】:我有一个 TimeDelta 列,其值如下所示:
2 天 21:54:00.000000000
我想要一个代表天数的浮点数,假设这里 2+21/24 = 2.875,忽略分钟。 有没有一种简单的方法可以做到这一点? 我看到一个答案建议
res['Ecart_lacher_collecte'].apply(lambda x: float(x.item().days+x.item().hours/24.))
但是我得到“AttributeError: 'str' object has no attribute 'item'”
Numpy 版本是 '1.10.4' 熊猫版本是 u'0.17.1'
这些列最初是通过以下方式获得的:
lac['DateHeureLacher'] = pd.to_datetime(lac['Date lacher']+' '+lac['Heure lacher'],format='%d/%m/%Y %H:%M:%S')
cap['DateCollecte'] = pd.to_datetime(cap['Date de collecte']+' '+cap['Heure de collecte'],format='%d/%m/%Y %H:%M:%S')
在第一个脚本中。然后在第二个:
res = pd.merge(lac, cap, how='inner', on=['Loc'])
res['DateHeureLacher'] = pd.to_datetime(res['DateHeureLacher'],format='%Y-%m-%d %H:%M:%S')
res['DateCollecte'] = pd.to_datetime(res['DateCollecte'],format='%Y-%m-%d %H:%M:%S')
res['Ecart_lacher_collecte'] = res['DateCollecte'] - res['DateHeureLacher']
也许将其保存为 csv 将其类型更改回字符串?我正在尝试进行的转换是在第三个脚本中。
Sexe_x PiegeLacher latL longL Loc Col_x DateHeureLacher Nb envolees PiegeCapture latC longC Col_y Sexe_y Effectif DateCollecte DatePose Ecart_lacher_collecte Dist_m
M Q0-002 1629238 237877 H Rouge 2011-02-04 17:15:00 928 Q0-002 1629238 237877 Rouge M 1 2011-02-07 15:09:00 2011-02-07 12:14:00 2 days 21:54:00.000000000 0
M Q0-002 1629238 237877 H Rouge 2011-02-04 17:15:00 928 Q0-002 1629238 237877 Rouge M 4 2011-02-07 12:14:00 2011-02-07 09:42:00 2 days 18:59:00.000000000 0
M Q0-002 1629238 237877 H Rouge 2011-02-04 17:15:00 928 Q0-003 1629244 237950 Rouge M 1 2011-02-07 15:10:00 2011-02-07 12:16:00 2 days 21:55:00.000000000 75
res.info():
Sexe_x 922 non-null object
PiegeLacher 922 non-null object
latL 922 non-null int64
longL 922 non-null int64
Loc 922 non-null object
Col_x 922 non-null object
DateHeureLacher 922 non-null object
Nb envolees 922 non-null int64
PiegeCapture 922 non-null object
latC 922 non-null int64
longC 922 non-null int64
Col_y 922 non-null object
Sexe_y 922 non-null object
Effectif 922 non-null int64
DateCollecte 922 non-null object
DatePose 922 non-null object
Ecart_lacher_collecte 922 non-null object
Dist_m 922 non-null int64
【问题讨论】:
我认为你可以使用float(res['columnName'].dt.days + res['columnName'].dt.hours / 24)
IIUC 你可以做res['columnname'].dt.total_seconds()/ (24 * 60 * 60)
@AntonProtopopov 我得到“AttributeError: Can only use .dt accessor with datetimelike values”
@EdChum 我得到“AttributeError:'Series'对象没有属性'total_seconds'”
@alpagarou 首先,您需要将列转换为 datetime
对象。你可以用pd.to_datetime
【参考方案1】:
您可以使用pd.to_timedelta
或np.timedelta64
定义持续时间并除以:
# set up as per @EdChum
df['total_days_td'] = df['time_delta'] / pd.to_timedelta(1, unit='D')
df['total_days_td'] = df['time_delta'] / np.timedelta64(1, 'D')
【讨论】:
也可以使用 datetime 模块,例如 datetime.timedelta(days=1)【参考方案2】:您可以使用dt.total_seconds
并将其除以一天中的总秒数,例如:
In [25]:
df = pd.DataFrame('dates':pd.date_range(dt.datetime(2016,1,1, 12,15,3), periods=10))
df
Out[25]:
dates
0 2016-01-01 12:15:03
1 2016-01-02 12:15:03
2 2016-01-03 12:15:03
3 2016-01-04 12:15:03
4 2016-01-05 12:15:03
5 2016-01-06 12:15:03
6 2016-01-07 12:15:03
7 2016-01-08 12:15:03
8 2016-01-09 12:15:03
9 2016-01-10 12:15:03
In [26]:
df['time_delta'] = df['dates'] - pd.datetime(2015,11,6,8,10)
df
Out[26]:
dates time_delta
0 2016-01-01 12:15:03 56 days 04:05:03
1 2016-01-02 12:15:03 57 days 04:05:03
2 2016-01-03 12:15:03 58 days 04:05:03
3 2016-01-04 12:15:03 59 days 04:05:03
4 2016-01-05 12:15:03 60 days 04:05:03
5 2016-01-06 12:15:03 61 days 04:05:03
6 2016-01-07 12:15:03 62 days 04:05:03
7 2016-01-08 12:15:03 63 days 04:05:03
8 2016-01-09 12:15:03 64 days 04:05:03
9 2016-01-10 12:15:03 65 days 04:05:03
In [27]:
df['total_days_td'] = df['time_delta'].dt.total_seconds() / (24 * 60 * 60)
df
Out[27]:
dates time_delta total_days_td
0 2016-01-01 12:15:03 56 days 04:05:03 56.170174
1 2016-01-02 12:15:03 57 days 04:05:03 57.170174
2 2016-01-03 12:15:03 58 days 04:05:03 58.170174
3 2016-01-04 12:15:03 59 days 04:05:03 59.170174
4 2016-01-05 12:15:03 60 days 04:05:03 60.170174
5 2016-01-06 12:15:03 61 days 04:05:03 61.170174
6 2016-01-07 12:15:03 62 days 04:05:03 62.170174
7 2016-01-08 12:15:03 63 days 04:05:03 63.170174
8 2016-01-09 12:15:03 64 days 04:05:03 64.170174
9 2016-01-10 12:15:03 65 days 04:05:03 65.170174
【讨论】:
是的,它有效,但我很震惊他们没有 dt.total_days() 或 dt.total_hours 可用... @LedgerYu 因为它不是 timedelta 的标准方法,另外它自己计算也很简单,但如果我们按照你的逻辑,我们就会有 total_days、total_hours、total_quarters、total_years、total_milliseconds 等方法. 你可以只做dt.days
,而不是作为一个函数。为我工作!
@Guillochon dt.days
只会给你天数,会抛出所有时间信息【参考方案3】:
你试过用这个代替吗?
res['Ecart_lacher_collecte'].apply(lambda x: (x.total_seconds()//(3600*24)) + (x.total_seconds()%(3600*24)//3600)/24))
第一个术语是 Day(在您的情况下为 2) 第二项是忽略分钟的小时比率(在您的情况下为 21/24)
如果你不想忽略分钟和秒数据,而是需要一个考虑一天中所有秒数的比率,代码如下:
res['Ecart_lacher_collecte'].apply(lambda x: (x.total_seconds()/(3600*24))
【讨论】:
为什么要拆分部门,然后就这样合并呢?与 x.total_seconds()/(3600*24) 的唯一区别是不完整的小时数根本不计算在内,我怀疑这是期望的行为。 是的,没错。不完整的小时数不计算在内。那是因为最初的海报是这样想的:“我想要一个代表天数的浮点数,假设这里是 2+21/24 = 2.875,忽略分钟。” @EliasHasle 我已经编辑了答案,其中我提到了为什么不考虑不完整的时间。以上是关于从 TimeDelta 到 Pandas 中的浮动天数的主要内容,如果未能解决你的问题,请参考以下文章
从 timedelta 构建 Pandas pd.tseries.offsets
如何将 timedelta 转换为 pandas 中的时间?
如何在转换 timedelta 变量时消除 pandas 中的错误?