Python的大熊猫不正确的日期计
与下面的Python大熊猫据帧“DF”工作:Python的大熊猫不正确的日期计
Customer_ID | Transaction_ID | Item_ID
ABC 2017-04-12-333 X8973
ABC 2017-04-12-333 X2468
ABC 2017-05-22-658 X2906
ABC 2017-05-22-757 X8790
ABC 2017-07-13-864 X8790
BCD 2017-08-11-879 X2346
BCD 2017-08-11-879 X2468
我想算的交易有一列表示,当它的客户端的第一次交易,第二个交易等按日期排列。 (如果同一天有两笔交易,我将它们统计为同一笔数字,因为我没有时间,所以我不知道哪一笔先到了 - 基本上把它们当作一笔交易处理)。
#get the date out of the Transaction_ID string
df['date'] = pd.to_datetime(df.Transaction_ID.str[:10])
#calculate the transaction number
df['trans_nr'] = df.groupby(['Customer_ID',"Transaction_ID", df['date'].dt.year]).cumcount()+1
不幸的是,这是我用上面的代码输出:
Customer_ID | Transaction_ID | Item_ID | date | trans_nr
ABC 2017-04-12-333 X8973 2017-04-12 1
ABC 2017-04-12-333 X2468 2017-04-12 2
ABC 2017-05-22-658 X2906 2017-05-22 1
ABC 2017-05-22-757 X8790 2017-05-22 1
ABC 2017-07-13-864 X8790 2017-07-13 1
BCD 2017-08-11-879 X2346 2017-08-11 1
BCD 2017-08-11-879 X2468 2017-08-11 2
这是不正确,这是正确的输出我要找:
Customer_ID | Transaction_ID | Item_ID | date | trans_nr
ABC 2017-04-12-333 X8973 2017-04-12 1
ABC 2017-04-12-333 X2468 2017-04-12 1
ABC 2017-05-22-658 X2906 2017-05-22 2
ABC 2017-05-22-757 X8790 2017-05-22 2
ABC 2017-07-13-864 X8790 2017-07-13 3
BCD 2017-08-11-879 X2346 2017-08-11 1
BCD 2017-08-11-879 X2468 2017-08-11 1
也许逻辑应仅基于Customer_ID和日期(没有Transaction_ID)?
我想这
df['trans_nr'] = df.groupby(['Customer_ID','date').cumcount()+1
但也算正确。
让我们尝试:
df['trans_nr'] = df.groupby(['Customer_ID', df['date'].dt.year])['date']\
.transform(lambda x: (x.diff() != pd.Timedelta('0 days')).cumsum())
输出:
Customer_ID Transaction_ID Item_ID date trans_nr
0 ABC 2017-04-12-333 X8973 2017-04-12 1
1 ABC 2017-04-12-333 X2468 2017-04-12 1
2 ABC 2017-05-22-658 X2906 2017-05-22 2
3 ABC 2017-05-22-757 X8790 2017-05-22 2
4 ABC 2017-07-13-864 X8790 2017-07-13 3
5 BCD 2017-08-11-879 X2346 2017-08-11 1
6 BCD 2017-08-11-879 X2468 2017-08-11 1
的一种方法是使累计计数之前下降重复值:
trans_nr = (df
.drop_duplicates(subset=['Customer_ID', 'date'])
.set_index(['Customer_ID', 'date'])
.groupby(level='Customer_ID')
.cumcount() + 1
)
df.set_index(['Customer_ID', 'date'], inplace=True)
df['trans_nr'] = trans_nr
df.reset_index(inplace=True)
要获得交易编号,你先用重复Customer_ID
和date
值删除行。然后,您使用Customer_ID
和date
(稍后合并)设置其索引并执行groupby
和cumcount
。这产生了一个系列,其值是每个Customer_ID
和date
的累计计数。
您还设置原始数据帧的索引(再次以允许合并)。然后,您只需将trans_nr
系列分配到df
中的一列。指数处理合并逻辑。
好点 - 一定是错过了。 – ASGM
使用dual groupby
与ngroup()
即
df['trans_nr'] = df.groupby('Customer_ID').apply(lambda x : \
x.groupby([x['date'].dt.date]).ngroup()+1).values
Customer_ID Transaction_ID Item_ID date trans_nr 0 ABC 2017-04-12-333 X8973 2017-04-12 1 1 ABC 2017-04-12-333 X2468 2017-04-12 1 2 ABC 2017-05-22-658 X2906 2017-05-22 2 3 ABC 2017-05-22-757 X8790 2017-05-22 2 4 ABC 2017-07-13-864 X8790 2017-07-13 3 5 BCD 2017-08-11-879 X2346 2017-08-11 1 6 BCD 2017-08-11-879 X2468 2017-08-11 1
您的解决方案使用两个groupbys而不是一个。我认为这将比我的慢两倍。你可以使用ngroup将它凝聚成一个群组吗? –
我同意,因为它是假设重置我使用了两次。让我尝试 – Dark
你能解释一下trans_nr = 1为seconrd记录。当我运行你的代码时,trans_nr为第二条记录= 2.我得到[1 2 1 1 1 1 2]不是[1 1 1 2 2 1 2] –
对不起 - 我正在试验计数并粘贴错误 - 我需要得到[1 1 2 2 3 1 1],尽管 – jeangelj
为什么第二个记录1?前两个记录有什么不同,我只看到Item_ID? –