簡體   English   中英

Pandas dataframe 列中列表值的過濾器列表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM