Pandas 数据框中基于 id 列的多个日期之间的差异
difference between multiple dates based on id column in a Pandas dataframe
我的实际案例如下,在一家商店中,我想知道第一次访问和第二次访问之间、第二次访问和第三次访问之间的访问时间(以天为单位)...
我有一个包含 2 列的 python 数据集(每个客户的访问 ID 和访问日期)
data = {'Id': ['A', 'B','A','B','A','A'],
'Date': ['01/03/2022', '03/03/2022', '05/03/2022', '07/03/2022', '09/03/2022','11/03/2022']
}
我的问题:对于已经来过4次的客户,第一次到第二次到访的间隔天数是多少?第 2 次和第 3 次访问之间的相同问题...
您可以先将它们转换为 pd.Timestamp
对象,然后按
对 ID 和日期进行排序
df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)
df = df.sort_values(['Id', 'Date'])
然后,您可以简单地计算时间戳的差异,乘以是否为同一用户的布尔掩码:
df['Date Since Last Visit'] = (df['Date'] - df['Date'].shift(1)) * (df['Id'] == df['Id'].shift())
df['Date Since Last Visit'] = df['Date Since Last Visit'].fillna(pd.Timedelta(0))
这会给你 timedelta 对象,你可以看到它已经过了多少天。
您的输出将是:
Id Date Date Since Last Visit
0 A 2022-03-01 0 days
2 A 2022-03-05 4 days
4 A 2022-03-09 4 days
5 A 2022-03-11 2 days
1 B 2022-03-03 0 days
3 B 2022-03-07 4 days
或者只过滤掉以下之后的首次访问:
df['Date Since Last Visit'] = df['Date'] - df['Date'].shift(1)
df = df[df['Id'] == df['Id'].shift()]
这给你:
Id Date Date Since Last Visit
2 A 2022-03-05 4 days
4 A 2022-03-09 4 days
5 A 2022-03-11 2 days
3 B 2022-03-07 4 days
您期望的输出不清楚,但让我们计算一个 2D table,其中客户作为索引,访问作为列:
# convert to datetime (assuming DD/MM/YYYY)
df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)
# setting up group
g = df.groupby('Id')['Date']
df2 = (df
.sort_values(by='Id') # ensure the dates are ordered
.assign(visit=g.cumcount().add(1), # visit number
nb_visits=g.transform('count'), # total number of visits
diff=g.diff() # difference between successive visits
)
.query('nb_visits >= 4') # filter to keep customers with at least 4 visits
.pivot(index='Id', columns='visit', values='diff') # reshape to 2D
)
输出:
这给出了每位客户自上次访问以来的天数(如果访问次数超过 3 次)
visit 1 2 3 4
Id
A NaT 4 days 4 days 2 days
注意。您可以在此处删除第一列,因为它始终未定义 (NaT)
我的实际案例如下,在一家商店中,我想知道第一次访问和第二次访问之间、第二次访问和第三次访问之间的访问时间(以天为单位)...
我有一个包含 2 列的 python 数据集(每个客户的访问 ID 和访问日期)
data = {'Id': ['A', 'B','A','B','A','A'],
'Date': ['01/03/2022', '03/03/2022', '05/03/2022', '07/03/2022', '09/03/2022','11/03/2022']
}
我的问题:对于已经来过4次的客户,第一次到第二次到访的间隔天数是多少?第 2 次和第 3 次访问之间的相同问题...
您可以先将它们转换为 pd.Timestamp
对象,然后按
df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)
df = df.sort_values(['Id', 'Date'])
然后,您可以简单地计算时间戳的差异,乘以是否为同一用户的布尔掩码:
df['Date Since Last Visit'] = (df['Date'] - df['Date'].shift(1)) * (df['Id'] == df['Id'].shift())
df['Date Since Last Visit'] = df['Date Since Last Visit'].fillna(pd.Timedelta(0))
这会给你 timedelta 对象,你可以看到它已经过了多少天。
您的输出将是:
Id Date Date Since Last Visit
0 A 2022-03-01 0 days
2 A 2022-03-05 4 days
4 A 2022-03-09 4 days
5 A 2022-03-11 2 days
1 B 2022-03-03 0 days
3 B 2022-03-07 4 days
或者只过滤掉以下之后的首次访问:
df['Date Since Last Visit'] = df['Date'] - df['Date'].shift(1)
df = df[df['Id'] == df['Id'].shift()]
这给你:
Id Date Date Since Last Visit
2 A 2022-03-05 4 days
4 A 2022-03-09 4 days
5 A 2022-03-11 2 days
3 B 2022-03-07 4 days
您期望的输出不清楚,但让我们计算一个 2D table,其中客户作为索引,访问作为列:
# convert to datetime (assuming DD/MM/YYYY)
df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)
# setting up group
g = df.groupby('Id')['Date']
df2 = (df
.sort_values(by='Id') # ensure the dates are ordered
.assign(visit=g.cumcount().add(1), # visit number
nb_visits=g.transform('count'), # total number of visits
diff=g.diff() # difference between successive visits
)
.query('nb_visits >= 4') # filter to keep customers with at least 4 visits
.pivot(index='Id', columns='visit', values='diff') # reshape to 2D
)
输出:
这给出了每位客户自上次访问以来的天数(如果访问次数超过 3 次)
visit 1 2 3 4
Id
A NaT 4 days 4 days 2 days
注意。您可以在此处删除第一列,因为它始终未定义 (NaT)