相对于同一列中的其他值(自上次事务以来的时间)创建列Pandas

时间:2015-11-16 01:12:53

标签: python pandas

我的数据集有两列包含用户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

2 个答案:

答案 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]