首页 > 解决方案 > 逐列检查数组中的元素是否存在于另一个数组中

问题描述

所以我有两个如下所示的数组:

x1 = np.array([['a','b','c'],['d','a','b'],['c','a,c','c']])
x2 = np.array(['d','c','d'])

我想检查每个元素是否x2存在于x1. 所以我尝试了:

print((x1==x2).any(axis=0))
#array([ True, False, False])

请注意x2[1] in x1[2,1] == True. 问题是,有时我们要查找的元素位于某个元素内部x1(如果我们用逗号分隔,则可以在其中识别它)。所以我想要的输出是:

array([ True,  True, False])

有没有办法使用 numpy(或 pandas)本机方法来做到这一点?

标签: pythonnumpy

解决方案


您可以vectorize使用广播功能x2 in x1.split(',')

@np.vectorize
def f(a, b):
    return b in a.split(',')

f(x1, x2).any(axis=0)
# array([ True,  True, False])

请注意,“矢量化”是用词不当。这不是真正的矢量化,只是广播自定义函数的便捷方式。


由于您在括号中提到了 pandas,因此另一种选择是applydf = pd.DataFrame(x1).

但是,numpy 函数要快得多:

f(x1, x2).any(axis=0)         # 24.2 µs ± 2.8 µs
df.apply(list_comp).any()     # 913 µs ± 12.1 µs
df.apply(combine_in).any()    # 1.8 ms ± 104 µs
df.apply(expand_eq_any).any() # 3.28 ms ± 751 µs
# use a list comprehension to do the splitting and membership checking:
def list_comp(col):
    return [x2[col.name] in val.split(',') for val in col]
# split the whole column and use `combine` to check `x2 in x1`
def combine_in(col):
    return col.str.split(',').combine(x2[col.name], lambda a, b: b in a)
# split the column into expanded columns and check the expanded rows for matches
def expand_eq_any(col):
    return col.str.split(',', expand=True).eq(x2[col.name]).any(axis=1)

推荐阅读