Python 检查一个df中的值是否在第二个df列的列表中

Python 检查一个df中的值是否在第二个df列的列表中,python,pandas,performance,dataframe,optimization,Python,Pandas,Performance,Dataframe,Optimization,我有两个数据帧 df1:有4列,每列都有一个包含值的列表 df2:有一列(列)该列有1个值 我想检查df2(col)中的任何值是否在df1(col1)或df1(col2)行中的任何列表中,然后保存该行(df1和4列) 下面是一些随机数据作为示例: df1 = pd.DataFrame({'col1': [[32, 24, 5, 6], [4, 8, 14], [12, 32, 234, 15, 6], [45]],

我有两个数据帧 df1:有4列,每列都有一个包含值的列表 df2:有一列(列)该列有1个值

我想检查df2(col)中的任何值是否在df1(col1)或df1(col2)行中的任何列表中,然后保存该行(df1和4列)

下面是一些随机数据作为示例:

df1 = pd.DataFrame({'col1': [[32, 24, 5, 6], [4, 8, 14], 
                            [12, 32, 234, 15, 6], [45]], 
                    'col2': [[13, 333 ,5], [32, 28, 5, 9], 
                            [4], [12, 45, 21]],
                    'col3': [['AS', 'EWE', 'SADF', 'EW'], 
                            ['EW', 'HHT', 'IYT'], ['C', 'KJG', 'TF', 'VC', 'D'], ['BX']], 
                    'col4': [['HG', 'FDGD' ,'F'], ['FDG', 'Y', 'FS', 'RT'], 
                            ['T'], ['XC', 'WE', 'TR']]
                    })

df2 = pd.DataFrame({'col': [1, 333, 8, 11, 45]})
df1:

df2:

这段代码运行得很好,但我使用的是大数据,所以需要花很多时间才能完成。 所以我想知道是否有任何方法可以优化它

for index, row in df1.iterrows():
    if (any(itm in row['col1'] for itm in df2['col'])):
        df3 = df3.append(row)
    elif (any(itm in row['col2'] for itm in df2['col'])):
        df3 = df3.append(row)
这就是输出的样子:

             col1            col2                 col3              col4
0  [32, 24, 5, 6]    [13, 333, 5]  [AS, EWE, SADF, EW]     [HG, FDGD, F]
1      [4, 8, 14]  [32, 28, 5, 9]       [EW, HHT, IYT]  [FDG, Y, FS, RT]
3            [45]    [12, 45, 21]                 [BX]      [XC, WE, TR]
输出可以是新的df,也可以是df1中带有“1”或“0”的列(如果值不在这两列中的任何一列中)

更新:

遵循cs95方法,我能够提高代码的性能


我以前的代码需要55秒,而他的方法只有8毫秒,因此大约需要x690的加速。

当然,我们可以使用设置查找来加速:

lookup = {*df2['col']}
df1[~df1[['col1', 'col2']].applymap(lookup.isdisjoint).all(axis=1)]

             col1            col2                 col3              col4
0  [32, 24, 5, 6]    [13, 333, 5]  [AS, EWE, SADF, EW]     [HG, FDGD, F]
1      [4, 8, 14]  [32, 28, 5, 9]       [EW, HHT, IYT]  [FDG, Y, FS, RT]
3            [45]    [12, 45, 21]                 [BX]      [XC, WE, TR]
处理列表列很难。通过识别,我们可以使用
applymap
,因为
df1['col1']
df1['col2']
中的每个单元格都必须进行相同的检查(在
df2['col']
上进行查找)。然后使用一点布尔逻辑来确定要删除哪些行,您就得到了最终结果

使用
iterrows
append
时,您的代码会受到双重打击。永远不要在数据帧上迭代,因为它很慢并且浪费内存,永远不要因为同样的原因增长数据帧



当然,我们可以使用设置查找来加快速度:

lookup = {*df2['col']}
df1[~df1[['col1', 'col2']].applymap(lookup.isdisjoint).all(axis=1)]

             col1            col2                 col3              col4
0  [32, 24, 5, 6]    [13, 333, 5]  [AS, EWE, SADF, EW]     [HG, FDGD, F]
1      [4, 8, 14]  [32, 28, 5, 9]       [EW, HHT, IYT]  [FDG, Y, FS, RT]
3            [45]    [12, 45, 21]                 [BX]      [XC, WE, TR]
处理列表列很难。通过识别,我们可以使用
applymap
,因为
df1['col1']
df1['col2']
中的每个单元格都必须进行相同的检查(在
df2['col']
上进行查找)。然后使用一点布尔逻辑来确定要删除哪些行,您就得到了最终结果

使用
iterrows
append
时,您的代码会受到双重打击。永远不要在数据帧上迭代,因为它很慢并且浪费内存,永远不要因为同样的原因增长数据帧



您好,谢谢您的接受。修改后的解决方案的加速系数是多少?您好,谢谢您的帮助!我将更多地研究如何编写更高效的代码。加速系数约为X690您好,感谢您的接受。修改后的解决方案的加速系数是多少?您好,谢谢您的帮助!我将更多地研究如何编写更高效的代码。加速系数约为x690
lookup = {*df2['col']}
df1[~df1[['col1', 'col2']].applymap(lookup.isdisjoint).all(axis=1)]

             col1            col2                 col3              col4
0  [32, 24, 5, 6]    [13, 333, 5]  [AS, EWE, SADF, EW]     [HG, FDGD, F]
1      [4, 8, 14]  [32, 28, 5, 9]       [EW, HHT, IYT]  [FDG, Y, FS, RT]
3            [45]    [12, 45, 21]                 [BX]      [XC, WE, TR]
lookup
# {1, 8, 11, 45, 333}

# get cells that have no elements in common
df1[['col1', 'col2']].applymap(lookup.isdisjoint)

    col1   col2
0   True  False
1  False   True
2   True   True
3  False  False

# get rows who have no columns in common
df1[['col1', 'col2']].applymap(lookup.isdisjoint).all(axis=1)
 
0    False
1    False
2     True
3    False
dtype: bool

# invert the condition to get rows to keep
~df1[['col1', 'col2']].applymap(lookup.isdisjoint).all(axis=1)

0     True
1     True
2    False
3     True
dtype: bool