从 pandas 多索引数据透视表中的时间序列计算值
Calculating values from time series in pandas multi-indexed pivot tables
我在 pandas 中有一个数据框,它存储一个人的 ID、交互质量和交互日期。一个人可以在多个日期进行多次交互,因此为了帮助可视化和绘制它,我将其转换为一个枢轴 table 首先按 Id 然后按日期分组以分析随时间变化的模式。
例如
import pandas as pd
df = pd.DataFrame({'Id':['A4G8','A4G8','A4G8','P9N3','P9N3','P9N3','P9N3','C7R5','L4U7'],
'Date':['2016-1-1','2016-1-15','2016-1-30','2017-2-12','2017-2-28','2017-3-10','2019-1-1','2018-6-1','2019-8-6'],
'Quality':[2,3,6,1,5,10,10,2,2]})
pt = df.pivot_table(values='Quality', index=['Id','Date'])
print(pt)
导致这个:
Id
Date
Quality
A4G8
2016-1-1
2
2016-1-15
4
2016-1-30
6
P9N3
2017-2-12
1
2017-2-28
5
2017-3-10
10
2019-1-1
10
C7R5
2018-6-1
2
L4U7
2019-8-6
2
不过,我也想...
- 测量每个 Id 的每次交互从第一次交互开始的时间
- 测量与上一次使用相同 Id 的交互的时间
所以我会得到一个 table 类似于下面的
Id
Date
Quality
Time From First
Time To Prev
A4G8
2016-1-1
2
0 days
NA days
2016-1-15
4
14 days
14 days
2016-1-30
6
29 days
14 days
P9N3
2017-2-12
1
0 days
NA days
2017-2-28
5
15 days
15 days
2017-3-10
10
24 days
9 days
Id列是字符串类型,我把date列转成datetime,Quality列转成整数。
该列相当大(>10,000 个唯一 ID),因此出于性能原因,我尽量避免使用 for 循环。我猜解决方案是以某种方式使用 pd.eval 但我不知道如何正确应用它。
抱歉,我是一个 python、pandas、& stack overflow) 菜鸟,我还没有在任何地方找到答案,所以即使是一些关于在哪里寻找的指示也会很棒 :- ).
非常感谢
将 Date
s 转换为日期时间,然后将每组的最小日期时间减去 GroupBy.transform
b subtracted by column Date
and for second new column use DataFrameGroupBy.diff
:
df['Date'] = pd.to_datetime(df['Date'])
df['Time From First'] = df['Date'].sub(df.groupby('Id')['Date'].transform('min'))
df['Time To Prev'] = df.groupby('Id')['Date'].diff()
print (df)
Id Date Quality Time From First Time To Prev
0 A4G8 2016-01-01 2 0 days NaT
1 A4G8 2016-01-15 3 14 days 14 days
2 A4G8 2016-01-30 6 29 days 15 days
3 P9N3 2017-02-12 1 0 days NaT
4 P9N3 2017-02-28 5 16 days 16 days
5 P9N3 2017-03-10 10 26 days 10 days
6 P9N3 2019-01-01 10 688 days 662 days
7 C7R5 2018-06-01 2 0 days NaT
8 L4U7 2019-08-06 2 0 days NaT
df["Date"] = pd.to_datetime(df.Date)
df = df.merge(
df.groupby(["Id"]).Date.first(),
on="Id",
how="left",
suffixes=["", "_first"]
)
df["Time From First"] = df.Date-df.Date_first
df['Time To Prev'] = df.groupby('Id').Date.diff()
df.set_index(["Id", "Date"], inplace=True)
df
输出:
我在 pandas 中有一个数据框,它存储一个人的 ID、交互质量和交互日期。一个人可以在多个日期进行多次交互,因此为了帮助可视化和绘制它,我将其转换为一个枢轴 table 首先按 Id 然后按日期分组以分析随时间变化的模式。
例如
import pandas as pd
df = pd.DataFrame({'Id':['A4G8','A4G8','A4G8','P9N3','P9N3','P9N3','P9N3','C7R5','L4U7'],
'Date':['2016-1-1','2016-1-15','2016-1-30','2017-2-12','2017-2-28','2017-3-10','2019-1-1','2018-6-1','2019-8-6'],
'Quality':[2,3,6,1,5,10,10,2,2]})
pt = df.pivot_table(values='Quality', index=['Id','Date'])
print(pt)
导致这个:
Id | Date | Quality |
---|---|---|
A4G8 | 2016-1-1 | 2 |
2016-1-15 | 4 | |
2016-1-30 | 6 | |
P9N3 | 2017-2-12 | 1 |
2017-2-28 | 5 | |
2017-3-10 | 10 | |
2019-1-1 | 10 | |
C7R5 | 2018-6-1 | 2 |
L4U7 | 2019-8-6 | 2 |
不过,我也想...
- 测量每个 Id 的每次交互从第一次交互开始的时间
- 测量与上一次使用相同 Id 的交互的时间
所以我会得到一个 table 类似于下面的
Id | Date | Quality | Time From First | Time To Prev |
---|---|---|---|---|
A4G8 | 2016-1-1 | 2 | 0 days | NA days |
2016-1-15 | 4 | 14 days | 14 days | |
2016-1-30 | 6 | 29 days | 14 days | |
P9N3 | 2017-2-12 | 1 | 0 days | NA days |
2017-2-28 | 5 | 15 days | 15 days | |
2017-3-10 | 10 | 24 days | 9 days |
Id列是字符串类型,我把date列转成datetime,Quality列转成整数。
该列相当大(>10,000 个唯一 ID),因此出于性能原因,我尽量避免使用 for 循环。我猜解决方案是以某种方式使用 pd.eval 但我不知道如何正确应用它。
抱歉,我是一个 python、pandas、& stack overflow) 菜鸟,我还没有在任何地方找到答案,所以即使是一些关于在哪里寻找的指示也会很棒 :- ). 非常感谢
将 Date
s 转换为日期时间,然后将每组的最小日期时间减去 GroupBy.transform
b subtracted by column Date
and for second new column use DataFrameGroupBy.diff
:
df['Date'] = pd.to_datetime(df['Date'])
df['Time From First'] = df['Date'].sub(df.groupby('Id')['Date'].transform('min'))
df['Time To Prev'] = df.groupby('Id')['Date'].diff()
print (df)
Id Date Quality Time From First Time To Prev
0 A4G8 2016-01-01 2 0 days NaT
1 A4G8 2016-01-15 3 14 days 14 days
2 A4G8 2016-01-30 6 29 days 15 days
3 P9N3 2017-02-12 1 0 days NaT
4 P9N3 2017-02-28 5 16 days 16 days
5 P9N3 2017-03-10 10 26 days 10 days
6 P9N3 2019-01-01 10 688 days 662 days
7 C7R5 2018-06-01 2 0 days NaT
8 L4U7 2019-08-06 2 0 days NaT
df["Date"] = pd.to_datetime(df.Date)
df = df.merge(
df.groupby(["Id"]).Date.first(),
on="Id",
how="left",
suffixes=["", "_first"]
)
df["Time From First"] = df.Date-df.Date_first
df['Time To Prev'] = df.groupby('Id').Date.diff()
df.set_index(["Id", "Date"], inplace=True)
df
输出: