【发布时间】:2022-01-17 18:02:59
【问题描述】:
抱歉标题含糊,我不完全确定如何更准确地用词。我有一个这样的数据框:
date customerID saved purchased savedProduct purchasedProduct
0 2021-01-01 456789 1 0 11223344 [0]
1 2021-01-01 456789 1 0 55667788 [0]
2 2021-01-03 456789 0 1 0 [11223344, 28373827]
这是用这个创建的:
d = {'date': ['2021-01-01', '2021-01-01', '2021-01-03'], 'customerID': ['456789', '456789', '456789'], 'saved':[1, 1, 0], 'purchased': [0, 0, 1], 'savedProduct': [11223344, 55667788, 0], 'purchasedProduct': [[0], [0], [11223344, 28373827]]}
df = pd.DataFrame(data=d)
其背后的逻辑是每一行都是一个客户记录:他们一次只能保存一个产品(这就是 savedProduct 有一个产品代码的原因)但他们可以购买多个产品,这就是为什么 purchaseProduct 包含一个列表。我想做的是:
- 通过 customerID,在 savedProduct 中获取唯一的 productID
- 通过此列中的唯一产品ID,查看它们是否出现在购买的产品中
- 如果它们出现,请从显示 purchaseProduct 的行中拉出日期列,以便我可以计算 savedProduct 和 purchaseProduct 之间的天数
因此,例如,第 1 行中的产品出现在第 3 行中,因此最好有一种方法在同一行,因此我们可以计算日期之间的差异。
我认为嵌套循环可以完成这项工作,但我无法让它工作(并且必须有更有效的方法..):
dateDF = pd.DataFrame({'customerID': ['0'],
'savedDate': ['0'],
'purchasedDate': ['0']})
dateDF_t = pd.DataFrame()
sp = []
for x in df['customerID'].unique():
customerID = x
sp = df[df['customerID'] == x]['savedProduct'].unique()
for i in sp:
for idx, n in enumerate(df[df['customerID'] == x]['purchasedProduct']):
if i in n and i != 0:
print(df[df['customerID'] == x].iloc[idx, 1])
dateDF_t['customerID'] = df[df['customerID'] == x].iloc[idx, 1]
dateDF_t['savedDate'] = df[(df['customerID'] == x) & (df['savedProduct'] == i)]['date']
dateDF_t['purchasedDate'] = df[df['customerID'] == x].iloc[idx, 0]
dateDF = pd.concat([dateDF, dateDF_t])
但是输出是这样的:
customerID savedDate purchasedDate
0 0 0 0
0 NaN 2021-01-01 2021-01-03
有什么方法可以更好地做到这一点,而且为什么 customerID 会产生 NaN?当我有输出(循环中的打印)时,它工作正常
感谢您的帮助!
编辑 - 可能只是使用列表解决了这个问题,但如果有人有更有效的方法,我们仍然会感激不尽!
sp = []
customerIDs = []
savedDates = []
purchasedDates = []
for x in df['customerID'].unique():
sp = df[df['customerID'] == x]['savedProduct'].unique()
for i in sp:
for idx, n in enumerate(df[df['customerID'] == x]['purchasedProduct']):
if i in n and i != 0:
customerIDs.append(df[df['customerID'] == x].iloc[idx, 1])
savedDates.append(df[(df['customerID'] == x) & (df['savedProduct'] == i)]['date'].values[0])
purchasedDates.append(df[df['customerID'] == x].iloc[idx, 0])
savedDF = pd.DataFrame({'customerID': customerIDs,
'savedDates': savedDates,
'purchasedDates': purchasedDates})
输出如下:
customerID savedDates purchasedDates
456789 2021-01-01 2021-01-03
2727228 2021-02-05 2021-02-09
【问题讨论】:
-
你能添加一个预期的输出吗?
-
已编辑谢谢保罗
-
我添加了一个答案,它比您自己要求的输出稍微复杂一些,但是从我的结果中您当然可以根据自己的喜好对其进行切片和切块。
-
顺便说一句,也许可以阅读一下这个答案:stackoverflow.com/questions/16476924/… 作为 Pandas 的初级用户,我发现它非常好