[英]Pandas filter list of list values in a dataframe column
我有一個 dataframe,如下所示
sample_df = pd.DataFrame({'single_proj_name': [['jsfk'],['fhjk'],['ERRW'],['SJBAK']],
'single_item_list': [['ABC_123'],['DEF123'],['FAS324'],['HSJD123']],
'single_id':[[1234],[5678],[91011],[121314]],
'multi_proj_name':[['AAA','VVVV','SASD'],['QEWWQ','SFA','JKKK','fhjk'],['ERRW','TTTT'],['SJBAK','YYYY']],
'multi_item_list':[[['XYZAV','ADS23','ABC_123'],['ABC_123','ADC_123']],['XYZAV','DEF123','ABC_123','SAJKF'],['QWER12','FAS324'],['JFAJKA','HSJD123']],
'multi_id':[[[2167,2147,29481],[5432,1234]],[2313,57567,2321,7898],[1123,8775],[5237,43512]]})
我想做以下
a) 從single_item_list
中為每一行選擇值
b) 在同一行的multi_item_list
列中搜索該值。 請注意,它可能是某些行list of lists
c) 如果找到匹配項,則只保留 multi_item_list 中的匹配值, multi_item_list
multi_item_list
刪除所有其他不匹配的值
d) 根據匹配項的position,在multi_id
列表中查找對應的值,只保留該項。 從列表中刪除所有其他 position 項
所以,我嘗試了以下但它不適用於列表的嵌套列表
for a, b, c in zip(sample_df['single_item_list'],sample_df['multi_item_list'],sample_df['multi_id']):
for i, x in enumerate(b):
print(x)
print(a[0])
if a[0] in x:
print(x.index(a[0]))
pos = x.index(a[0])
print(c[pos-1])
我希望我的 output 如下所示。 在現實世界中,我會有更多情況,例如第一個輸入行(具有多個級別的嵌套列表)
這是一種適用於任意數量的嵌套列表的方法:
def func(z, X, Y):
A, B = [], []
for x, y in zip(X, Y):
if isinstance(x, list):
a, b = func(z, x, y)
A.append(a), B.append(b)
if x == z:
A.append(x), B.append(y)
return A, B
c = ['single_item_list', 'multi_item_list', 'multi_id']
df[c[1:]] = [func(z, X, Y) for [z], X, Y in df[c].to_numpy()]
結果
single_proj_name single_item_list single_id multi_proj_name multi_item_list multi_id
0 [jsfk] [ABC_123] [1234] [AAA, VVVV, SASD] [[ABC_123], [ABC_123]] [[29481], [5432]]
1 [fhjk] [DEF123] [5678] [QEWWQ, SFA, JKKK, fhjk] [DEF123] [57567]
2 [ERRW] [FAS324] [91011] [ERRW, TTTT] [FAS324] [8775]
3 [SJBAK] [HSJD123] [121314] [SJBAK, YYYY] [HSJD123] [43512]
您提供的代碼使用 zip() function 同時迭代 DataFrame 的“single_item_list”、“multi_item_list”和“multi_id”列。
對於每次迭代,它使用嵌套的 for 循環來迭代“multi_item_list”列中的子列表。 它使用 in 運算符檢查當前子列表中是否存在“single_item_list”的第一個元素。 如果存在,則使用 index() 方法在子列表中找到匹配元素的索引,並將其分配給變量 pos。 然后它打印“multi_id”列的相應索引中的值。
此代碼將正常工作,但它僅在 multi_id 列中打印匹配值,它不會更新 DataFrame 的 multi_item_list 和 multi_id 列。為了使用匹配值更新 DataFrame,您必須使用 .iloc 方法來更新 Dataframe。例如:sample_df.iloc[i,j] = new_val
for i, (single, multi_item, multi_id) in enumerate(zip(sample_df['single_item_list'],sample_df['multi_item_list'],sample_df['multi_id'])):
for j, item_list in enumerate(multi_item):
if single[0] in item_list:
pos = item_list.index(single[0])
sample_df.at[i,'multi_item_list'] = [item_list]
sample_df.at[i,'multi_id'] = [multi_id[j]]
打印(sample_df)
這將使用“multi_item_list”和“multi_id”列中的過濾值打印更新后的 DataFrame。 請注意,print(sample_df) 應放在 for 循環之后,以確保在更新后打印表格。
此代碼同時迭代 DataFrame 的“single_item_list”、“multi_item_list”和“multi_id”列。 在每次迭代中,它使用嵌套的 for 循環來迭代“multi_item_list”列中的子列表。 它使用 in 運算符檢查當前子列表中是否存在“single_item_list”的第一個元素。 如果存在,則使用 index() 方法在子列表中找到匹配元素的索引,並將其分配給變量 pos。 然后,它使用 at 方法將當前索引處的 DataFrame 的“multi_item_list”和“multi_id”列更新為匹配值。
請注意,此代碼將從“multi_item_list”和“multi_id”列中刪除不匹配的項目,如果沒有匹配的項目,它將保留原始值。
我使用isinstance
來檢查它是否是嵌套列表,並想出了如下所示的結果,預期結果為 output。我願意為專家提供建議和改進
for i, (single, multi_item, multi_id) in enumerate(zip(sample_df['single_item_list'],sample_df['multi_item_list'],sample_df['multi_id'])):
if (any(isinstance(i, list) for i in multi_item)) == False:
for j, item_list in enumerate(multi_item):
if single[0] in item_list:
pos = item_list.index(single[0])
sample_df.at[i,'multi_item_list'] = [item_list]
sample_df.at[i,'multi_id'] = [multi_id[j]]
else:
print("under nested list")
for j, item_list in enumerate(zip(multi_item,multi_id)):
if single[0] in multi_item[j]:
pos = multi_item[j].index(single[0])
sample_df.at[i,'multi_item_list'][j] = single[0]
sample_df.at[i,'multi_id'][j] = multi_id[j][pos]
else:
sample_df.at[i,'multi_item_list'][j] = np.nan
sample_df.at[i,'multi_id'][j] = np.nan
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.