為模糊的標題道歉,我不完全確定如何更正確地表達它。我有一個像這樣的資料幀:
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,查看它們是否出現在已購買的產品中
- 如果它們出現,請從出現的采購產品行中拉出日期列,以便我可以計算出savedProduct 和采購產品之間的天數
因此,例如,第 1 行中的產品出現在第 3 行中,因此最好有一種方法可以將第一行的日期 (2021-01-01) 和第三行的日期 (2021-01-03) 放在同一行中,因此我們可以計算日期之間的差異。
我認為嵌套回圈可以完成這項作業,但我無法讓它作業(并且必須有更有效的方法..):
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
uj5u.com熱心網友回復:
嘗試:
df=df.explode('purchasedProduct').reset_index(drop=True)
df['purchase_date'] = df.groupby('customerID').apply(
lambda df: df.apply(
lambda x: np.nan if x.savedProduct == 0 else df.loc[df.purchasedProduct == x.savedProduct, 'date'], axis=1))
這將首先用已購買的產品中的串列分解行,因此它為串列中的每個專案創建一個單獨的行。然后它添加了一個購買日期列,因此您可以在行級別確定是否以及何時購買了該產品。
date customerID saved purchased savedProduct purchasedProduct purchase_date
2021-01-01 456789 1 0 11223344 0 2021-01-03
2021-01-01 456789 1 0 55667788 0 NaN
2021-01-03 456789 0 1 0 11223344 NaN
2021-01-03 456789 0 1 0 28373827 NaN
當然,您可以過濾 df 以僅包含包含已保存產品的行:
df.loc[df.saved==1]
date customerID saved purchased savedProduct purchasedProduct purchase_date
2021-01-01 456789 1 0 11223344 0 2021-01-03
2021-01-01 456789 1 0 55667788 0 NaN
或者只有某些列:
df.loc[df.saved==1, ['customerID', 'savedProduct', 'date',`'purchase_date']]
customerID savedProduct date purchase_date
456789 11223344 2021-01-01 2021-01-03
456789 55667788 2021-01-01 NaN
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/384592.html
