我的数据集有两列包含用户ID和事务时间。我想创建第三列,指示自上次用户购买以来的时间。例如:
User Id Timestamp
92212 2015-08-20T15:52:53
26123 2015-10-29T14:44:06
92212 2015-07-21T16:21:55
第三栏将包含以下内容:
1
0
0
其中1表示自上次购买后一个月(8月与7月),0表示首次购买(或者更适合NaN?)。
基本上,我需要对用户ID进行分组,按时间顺序排列事务时间并计算到先前时间顺序的距离。也可以采用任何其他方法来解决自上次按月以来的保留问题。
我现在把它打包成这样的代码:
def monthSinceLastOrder(transactionArray):
transactionArray = transactionArray.order()
monthValues = []
for transDate in transactionArray:
monthValues.append(transDate.month)
distance = [-1]
for i in monthValues:
if monthValues[0]==i:
prior=i
else:
distance.append(i-prior)
prior=i
return distance
答案 0 :(得分:0)
您正在描述Pandas Split-Apply-Combine
方法。 http://pandas.pydata.org/pandas-docs/stable/groupby.html
我们可以按用户ID分组,然后为每个组应用一个函数来评估行之间的差异。
让我们设置数据帧:
import pandas as pd
data = [
{'User Id': '9272', 'Timestamp': '2015-08-20T15:52:53'},
{'User Id': '26121', 'Timestamp': '2015-10-29T14:44:06'},
{'User Id': '9272', 'Timestamp': '2015-07-21T16:21:55'},
]
df = pd.DataFrame(data)
df['Timestamp'] = pd.to_datetime(df['Timestamp'])
现在定义一个将对每个组进行操作的函数,然后应用它。
函数按时间戳排序,并为每一行创建一个新的Delta
列,设置为自身与前一行之间的差异。如果没有前一行(即首次购买),则返回NaT。
def x(frame):
frame.sort('Timestamp', inplace=True)
frame['Delta'] = frame['Timestamp'] - frame['Timestamp'].shift(1)
return frame
df.groupby(['User Id'], group_keys=False).apply(x)
结果数据框如下所示:
Timestamp User Id Delta
1 2015-10-29 14:44:06 26121 NaT
2 2015-07-21 16:21:55 9272 NaT
0 2015-08-20 15:52:53 9272 29 days 23:30:58
答案 1 :(得分:0)
根据向量化操作考虑这个问题的方法是使用shift
来偏移时间戳列,然后只使用减法(这将沿着数组广播)
df.sort_values(by='Timestamp')\
.groupby('User')\
.apply(lambda x: x['Timestamp'] - x['Timestamp'].shift())
User
26123 1 NaT
92212 2 NaT
0 29 days 23:30:58
Name: Id, dtype: timedelta64[ns]