[英]Fill group column with last value of the last group
這是一個棘手的問題,我希望提高代碼性能。 想象一個像這樣的數據框:
TOUR_ID ID PAGE_ID CREATED DATE AVAILABILITY
T_1 ID1 P1 2018-07-03 19:10:19 AVAILABLE
T_1 ID1 P1 2018-07-03 19:10:20 AVAILABLE
T_1 ID1 P2 2018-07-03 19:12:33 AVAILABLE
T_1 ID2 P3 2018-07-03 19:13:34 AVAILABLE
T_1 ID2 P3 2018-07-03 19:13:35 NOT AVAILABLE
T_1 ID2 P4 2018-07-03 19:16:24 AVAILABLE
T_2 ID3 P4 2018-07-03 18:23:19 AVAILABLE
T_2 ID3 P4 2018-07-03 18:23:20 NOT AVAILABLE
T_2 ID1 P1 2018-07-03 19:10:21 NOT AVAILABLE
T_2 ID2 P3 2018-07-03 19:13:37 NOT AVAILABLE
T_2 ID2 P3 2018-07-03 19:13:38 NOT AVAILABLE
T_2 ID3 P5 2018-07-03 20:56:33 AVAILABLE
T_2 ID3 P5 2018-07-03 20:56:34 NOT AVAILABLE
T_2 ID3 P5 2018-07-03 22:56:35 AVAILABLE
T_2 ID3 P6 2018-07-03 22:57:20 NOT AVAILABLE
T_2 ID3 P7 2018-07-03 22:58:35 AVAILABLE
T_2 ID4 P8 2018-07-03 22:59:00 AVAILABLE
T_2 ID1 P1 2018-07-03 23:12:00 AVAILABLE
T_2 ID1 P3 2018-07-03 23:32:00 AVAILABLE
在每個組(Tour_ID、ID、Page_ID)上,我需要使用前一組的最后一個值創建一個列。 此外,在第一次 Tour_ID 或 ID 更改時,我將獲得 NaN,因為該組合沒有任何先前的值。
結果應該是這樣的:
TOUR_ID ID PAGE_ID CREATED DATE AVAILABILITY PREVIOUS AVAILABILITY
T_1 ID1 P1 2018-07-03 19:10:19 AVAILABLE NaN
T_1 ID1 P1 2018-07-03 19:10:20 AVAILABLE NaN
T_1 ID1 P2 2018-07-03 19:12:33 AVAILABLE AVAILABLE
T_1 ID2 P3 2018-07-03 19:13:34 AVAILABLE NaN
T_1 ID2 P3 2018-07-03 19:13:35 NOT_AVAILABLE NaN
T_1 ID2 P4 2018-07-03 19:16:24 AVAILABLE NOT_AVAILABLE
T_2 ID3 P4 2018-07-03 18:23:19 AVAILABLE NaN
T_2 ID3 P4 2018-07-03 18:23:20 NOT AVAILABLE NaN
T_2 ID1 P1 2018-07-03 19:10:21 NOT AVAILABLE NaN
T_2 ID2 P3 2018-07-03 19:13:37 NOT AVAILABLE NaN
T_2 ID2 P3 2018-07-03 19:13:38 NOT AVAILABLE NaN
T_2 ID3 P5 2018-07-03 20:56:33 AVAILABLE NOT AVAILABLE
T_2 ID3 P5 2018-07-03 20:56:34 NOT AVAILABLE NOT AVAILABLE
T_2 ID3 P5 2018-07-03 22:56:35 AVAILABLE NOT AVAILABLE
T_2 ID3 P6 2018-07-03 22:57:20 NOT AVAILABLE AVAILABLE
T_2 ID3 P7 2018-07-03 22:58:35 AVAILABLE NOT AVAILABLE
T_2 ID4 P8 2018-07-03 22:59:00 AVAILABLE NaN
T_2 ID1 P1 2018-07-03 23:12:00 AVAILABLE NaN
T_2 ID1 P3 2018-07-03 23:32:00 AVAILABLE AVAILABLE
我有一個運行的代碼,但它不能很好地擴展(數據框有大約 900,000 行)。 對提高代碼性能的任何幫助將不勝感激。
這是我到目前為止所擁有的:
for current_op in df.TOUR_ID.unique():
dummy = df[df.TOUR_ID == current_op].ID.unique()
for current_ID in dummy:
dummy_m = df[(df.TOUR_ID == current_op) & (df.ID == current_ID)].PAGE_ID.unique()
for current_page in dummy_m:
mask = (df.TOUR_ID == current_op) & (df.ID == current_ID) & (df.PAGE_ID == current_page)
indexes = mask.reset_index().rename(columns ={0:'Bool'})
ind = indexes.index[indexes['Bool'] == True].tolist()[0]
if (ind == 0) | ((current_page == dummy_m[0])):
df.loc[mask,'Previous_availability'] = np.nan
else:
previous_aval = df.AVAILABILITY.loc[indexes['index'].loc[ind-1]]
df.loc[mask, 'Previous_availability'] = previous_aval
注意:NaN 最終將被刪除
- 編輯
下面是創建數據框的代碼:
import pandas as pd
import numpy as np
df = pd.DataFrame([['T_1','ID1','P1','2018-07-03 19:10:19', 'AVAILABLE'],
['T_1','ID1','P1','2018-07-03 19:10:20', 'AVAILABLE'],
['T_1','ID1','P2','2018-07-03 19:12:33', 'AVAILABLE'],
['T_1','ID2','P3','2018-07-03 19:13:34', 'AVAILABLE'],
['T_1','ID2','P3','2018-07-03 19:13:35', 'NOT AVAILABLE'],
['T_1','ID2','P4','2018-07-03 19:16:24', 'AVAILABLE'],
['T_2','ID3','P4','2018-07-03 18:23:19', 'AVAILABLE'],
['T_2','ID3','P4','2018-07-03 18:23:20', 'NOT AVAILABLE'],
['T_2','ID1','P1','2018-07-03 19:10:21', 'NOT AVAILABLE'],
['T_2','ID2','P3','2018-07-03 19:13:36', 'NOT AVAILABLE'],
['T_2','ID2','P3','2018-07-03 19:13:37', 'NOT AVAILABLE'],
['T_2','ID3','P5','2018-07-03 20:56:33', 'AVAILABLE'],
['T_2','ID3','P5','2018-07-03 20:56:34', 'NOT AVAILABLE'],
['T_2','ID3','P5','2018-07-03 22:56:35', 'AVAILABLE'],
['T_2','ID3','P6','2018-07-03 22:57:20', 'NOT AVAILABLE'],
['T_2','ID3','P7','2018-07-03 22:58:35', 'AVAILABLE'],
['T_2','ID4','P8','2018-07-03 22:59:00', 'AVAILABLE'],
['T_2','ID1','P1','2018-07-03 23:12:00', 'AVAILABLE'],
['T_2','ID1','P3','2018-07-03 23:32:00', 'AVAILABLE']
], columns=['TOUR_ID','ID','PAGE_ID','CREATED DATE', 'AVAILABILITY'])
這是一個相當令人頭疼的問題,但這是解決這個問題的一種方法:
df = pd.read_csv('test.tsv').set_index(['TOUR_ID', 'ID', 'PAGE_ID'])
獲取每組的最后一行,向前移動一位:
shifted = df.groupby(['TOUR_ID', 'ID', 'PAGE_ID']).last().shift(1).reset_index()
現在我們對在PAGE_ID
看到變化但在ID
沒有變化的行感興趣,因此我們構造了一個布爾掩碼:
change = shifted != shifted.shift(1)
mask = np.array(change.PAGE_ID & ~change.ID & ~change.TOUR_ID)
最后,我們應用掩碼並加入以創建新列:
shifted.set_index(['TOUR_ID', 'ID', 'PAGE_ID'], inplace=True)
shifted[~mask] = np.nan
result = df.join(shifted['AVAILABILITY'], rsuffix='LAST')
好的,這是我的刺。
1) 創建助手系列P_INT
( PAGE_ID
整數部分)
2) 使用 MultiIndex ['TOUR_ID', 'ID', 'P_INT']
創建輔助 DataFrame df_last_availability
3) 將P_INT
偏移 1
4) 重置原始 df 的索引,使其與df_last_availability
匹配。 從這里您可以輕松合並(使用左連接)索引上的 2 個數據幀。
5)最后的鏈接方法只是清理以將數據幀返回到其原始形狀 - 即刪除輔助字段並將索引重置為其原始形狀。
df['P_INT'] = df.PAGE_ID.str.extract('(\d+)').astype(int)
df_last_availability = df.groupby(['TOUR_ID', 'ID', 'P_INT']).last()
df['P_INT'] = df.P_INT - 1
(df.set_index(['TOUR_ID', 'ID', 'P_INT'])
.merge(df_last_availability[['AVAILABILITY']], how='left',
left_index=True, right_index=True, suffixes=('', '_PREV'))
.reset_index()
.drop(['P_INT'], axis=1))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.