Skip to main content
 首页 » 编程设计

python之跨 Pandas DataFrame 中多列的映射方法

2025年05月04日15lovecherry

我有一个 Pandas 数据框,其中的值是列表:

import pandas as pd 
 
DF = pd.DataFrame({'X':[[1, 5], [1, 2]], 'Y':[[1, 2, 5], [1, 3, 5]]}) 
DF 
         X          Y 
0   [1, 5]  [1, 2, 5] 
1   [1, 2]  [1, 3, 5] 

我想检查 X 中的列表是否是 Y 中列表的子集。对于单个列表,我们可以使用 set(x).issubset(set(y)) 来完成此操作。但是我们如何跨 Pandas 数据列执行此操作?

到目前为止,我唯一想出的方法是使用单独的列表作为解决方法,然后将结果转换回 Pandas。这个任务似乎有点复杂:

foo = [set(DF['X'][i]).issubset(set(DF['Y'][i])) for i in range(len(DF['X']))] 
 
foo = pd.DataFrame(foo) 
foo.columns = ['x_sub_y'] 
pd.merge(DF, foo, how = 'inner', left_index = True, right_index = True) 
 
         X          Y   x_sub_y 
0   [1, 5]  [1, 2, 5]   True 
1   [1, 2]  [1, 3, 5]   False 

有没有更简单的方法来实现这一点?可能使用 .map 或 .apply?

请您参考如下方法:

选项 1
设置转换和差异使用np.where

df_temp = DF.applymap(set) 
DF['x_sub_y'] = np.where(df_temp.X - df_temp.Y, False, True) 
DF 
        X          Y  x_sub_y 
0  [1, 5]  [1, 2, 5]     True 
1  [1, 2]  [1, 3, 5]    False 

选项 2
更快的 astype 转换

DF['x_sub_y'] = ~(DF.X.apply(set) - DF.Y.apply(set)).astype(bool) 
DF  
        X          Y  x_sub_y 
0  [1, 5]  [1, 2, 5]     True 
1  [1, 2]  [1, 3, 5]    False 

选项 3
np.vectorize

的乐趣
def foo(x): 
     return not x 
 
v = np.vectorize(foo)     
DF['x_sub_y'] = v(DF.X.apply(set) - DF.Y.apply(set))  
DF 
        X          Y  x_sub_y 
0  [1, 5]  [1, 2, 5]     True 
1  [1, 2]  [1, 3, 5]    False 

扩展Scott Boston's answer使用相同的方法提高速度:

def foo(x, y): 
    return set(x).issubset(y) 
 
v = np.vectorize(foo) 
 
DF['x_sub_y'] = v(DF.X, DF.Y) 
DF 
        X          Y  x_sub_y 
0  [1, 5]  [1, 2, 5]     True 
1  [1, 2]  [1, 3, 5]    False 

小

1000 loops, best of 3: 460 µs per loop           # Before        
10000 loops, best of 3: 103 µs per loop          # After 

大(df * 10000)

1 loop, best of 3: 1.26 s per loop               # Before    
100 loops, best of 3: 13.3 ms per loop           # After