Python 一种快速、有效的方法来计算大熊猫行组之间的时间差?
假设我在一个数据框中有这个表,其中有几辆车的加油日期:Python 一种快速、有效的方法来计算大熊猫行组之间的时间差?,python,pandas,dataframe,Python,Pandas,Dataframe,假设我在一个数据框中有这个表,其中有几辆车的加油日期: +-------+-------------+ | carId | refill_date | +-------+-------------+ | 1 | 2020-03-01 | +-------+-------------+ | 1 | 2020-03-12 | +-------+-------------+ | 1 | 2020-04-04 | +-------+-------------+ |
+-------+-------------+
| carId | refill_date |
+-------+-------------+
| 1 | 2020-03-01 |
+-------+-------------+
| 1 | 2020-03-12 |
+-------+-------------+
| 1 | 2020-04-04 |
+-------+-------------+
| 2 | 2020-03-07 |
+-------+-------------+
| 2 | 2020-03-26 |
+-------+-------------+
| 2 | 2020-04-01 |
+-------+-------------+
我想添加第三列,time_Passed,以及每次加注之间的持续时间
+-------+-------------+--------------+
| carId | refill_date | time_elapsed |
+-------+-------------+--------------+
| 1 | 2020-03-01 | |
+-------+-------------+--------------+
| 1 | 2020-03-12 | 11 |
+-------+-------------+--------------+
| 1 | 2020-04-04 | 23 |
+-------+-------------+--------------+
| 2 | 2020-03-07 | |
+-------+-------------+--------------+
| 2 | 2020-03-26 | 19 |
+-------+-------------+--------------+
| 2 | 2020-04-01 | 6 |
+-------+-------------+--------------+
下面是我的工作:
作为pd进口熊猫
df=pd.DataFrame
数据=[
{
carId:1,
加注日期:2020-3-1
},
{
carId:1,
加注日期:2020-3-12
},
{
carId:1,
加注日期:2020-4-4
},
{
carId:2,
加注日期:2020-3-7
},
{
carId:2,
加注日期:2020-3-26
},
{
carId:2,
加注日期:2020-4-1
}
]
df=pd.DataFramedata
df['refill_date']=pd.to_datetimedf['refill_date']
对于df['carId']中的c。唯一性:
df.loc[df['carId']==c,'经过的时间']=df.loc[df['carId']==c,
“重新加注日期”].diff
它返回预期结果:
+---+-------+-------------+--------------+
| | carId | refill_date | time_elapsed |
+---+-------+-------------+--------------+
| 0 | 1 | 2020-03-01 | NaT |
+---+-------+-------------+--------------+
| 1 | 1 | 2020-03-12 | 11 days |
+---+-------+-------------+--------------+
| 2 | 1 | 2020-04-04 | 23 days |
+---+-------+-------------+--------------+
| 3 | 2 | 2020-03-07 | NaT |
+---+-------+-------------+--------------+
| 4 | 2 | 2020-03-26 | 19 days |
+---+-------+-------------+--------------+
| 5 | 2 | 2020-04-01 | 6 days |
+---+-------+-------------+--------------+
所以,看起来一切正常,但这里有一个陷阱:在我的现实生活实例中,我的数据帧包含350万行,处理需要很长时间,尽管这是一个完全数字化的内存计算,只有1711个组可以循环
有没有其他更快捷的方法
谢谢 通过使用重新加注日期并从中减去来获取经过的时间
(
df.assign(
refill_date=pd.to_datetime(df.refill_date),
time_shift=lambda x: x.groupby("carId").refill_date.shift(),
time_elapsed=lambda x: x.time_shift.sub(x.refill_date).abs(),
)
)
使用的其他答案更好,因为这更简洁,而且我相信更快。通过使用并减去重新加注日期来获取所用的时间
(
df.assign(
refill_date=pd.to_datetime(df.refill_date),
time_shift=lambda x: x.groupby("carId").refill_date.shift(),
time_elapsed=lambda x: x.time_shift.sub(x.refill_date).abs(),
)
)
使用的其他答案更好,因为这更简洁,而且我相信更快。您只需要使用。groupby:
输出:
refill_date
0 NaT
1 11 days
2 23 days
3 NaT
4 19 days
5 6 days
您只需使用。groupby:
输出:
refill_date
0 NaT
1 11 days
2 23 days
3 NaT
4 19 days
5 6 days
在df.groupby上使用本机pandas方法应能显著提高本机python循环的性能: df['time_appeased']=df.groupby'carId'['refill_date'].diff 这是我笔记本电脑上的一个小基准,YMMV。。。使用100辆车,每辆车使用31天, 性能提升近10倍: 作为pd进口熊猫 导入时间信息 数据=[{carId:carId,重新加注日期:2020-3-+strday}范围1100的carId,范围1,32的一天] df=pd.DataFramedata df['refill_date']=pd.to_datetimedf['refill_date'] def原始方法: 对于df['carId']中的c。唯一性: df.loc[df['carId']==c,'经过的时间']=df.loc[df['carId']==c, “重新加注日期”].diff def使用_groupby: df['time_appeased']=df.groupby'carId'['refill_date'].diff time1=timeit.timeit‘原始_方法’,globals=globals,number=100 time2=timeit.timeit'using_groupby',globals=globals,number=100 打印时间1 打印时间2 打印时间1/2 输出:
16.6183732
1.7910263000000022
9.278687420726307
在df.groupby上使用本机pandas方法应能显著提高本机python循环的性能: df['time_appeased']=df.groupby'carId'['refill_date'].diff 这是我笔记本电脑上的一个小基准,YMMV。。。使用100辆车,每辆车使用31天, 性能提升近10倍: 作为pd进口熊猫 导入时间信息 数据=[{carId:carId,重新加注日期:2020-3-+strday}范围1100的carId,范围1,32的一天] df=pd.DataFramedata df['refill_date']=pd.to_datetimedf['refill_date'] def原始方法: 对于df['carId']中的c。唯一性: df.loc[df['carId']==c,'经过的时间']=df.loc[df['carId']==c, “重新加注日期”].diff def使用_groupby: df['time_appeased']=df.groupby'carId'['refill_date'].diff time1=timeit.timeit‘原始_方法’,globals=globals,number=100 time2=timeit.timeit'using_groupby',globals=globals,number=100 打印时间1 打印时间2 打印时间1/2 输出:
16.6183732
1.7910263000000022
9.278687420726307
还可以考虑浮点列的链接。dt.Day.使用GROMPBY的问题是,我没有得到预期的输出。我不想做一个聚合,而是在原始列中添加一个新列。如果我运行df.groupby'carId'.diff.reset_index,我将不再具有映射时差的carId。我可以假设所有行的顺序都相同,并且我可以将表并排连接到pd.concat[df,df.groupby'carId.diff],axis=1吗?看起来确实存在匹配。我没想到groupby会这么做,因为我不想收集数据,但我现在知道它不仅仅是聚合-还可以考虑浮点列的链接。dt.Day.使用GROMPBY的问题是,我没有得到预期的输出。我不想做一个聚合,而是在原始列中添加一个新列。如果我运行df.groupby'carId'.diff.reset_index,我将不再具有映射时差的carId。我可以假设所有行的顺序都相同,并且我可以将表并排连接到pd.concat[df,df.groupby'carId.diff],axis=1吗?看起来确实存在匹配。我不认为groupby会这么做,因为我不想收集数据,但现在我知道它做了很多事情 比聚合更重要!:-