numpy.intersect1d 不适用于 Dictionary.keys()

问题描述 投票:0回答:2

我尝试使用numpy的

intersect1d
来比较两个字典中的键。然而,由于与字典键是对象相关的某种原因,这总是返回零的交集。我想知道为什么这种行为在任何方面都是可取的。

d1 = {'a':1, 'b':2}
d2 = {'b':2, 'c':3}
np.intersect1d(d1.keys(), d2.keys())
> array([], dtype=object)

但是,

np.intersect1d(list(d1.keys()), list(d2.keys()))
> array(['b'], dtype='<U1')

这是预期行为吗?如果是,为什么?

python numpy dictionary set
2个回答
0
投票

字典键是特殊对象(类似集合),它们是字典键的动态视图(请参阅doc)。它们的行为确实“出乎意料”(例如,您不能像列表一样对它们进行切片:

d1.keys()[0]

现在我不确定为什么

np.intersect1d
dict.keys()
上没有按预期工作,但为什么在这里使用numpy呢?该函数被定义为适用于数组,而不是任何对象。

此外,由于对象需要转换为数组,这比纯 python 慢。最好使用简单的

set
交叉点
set(d1) & set(d2)
:

d1 = dict.fromkeys(range(1, 1_000_000))
d2 = dict.fromkeys(range(1, 2_000_000, 2))

%timeit np.intersect1d(list(d1), list(d2))
# 565 ms ± 21.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit set(d1) & set(d2)
# 225 ms ± 6.34 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

0
投票

intersect1d()
的参数是

ar1, ar2array_like
    Input arrays. Will be flattened if not already 1D.

参见https://numpy.org/doc/stable/reference/ generated/numpy.intersect1d.html

dict.keys()
的返回值是字典视图objects,参见https://docs.python.org/3/library/stdtypes.html#dict-views。因此,
numpy
将这些视图对象转换为对象数组,因为它们不是数字的集合:

>>> np.array({'a':1, 'b':2}.keys())
array(dict_keys(['a', 'b']), dtype=object)

现在

intersect1d()
将失败,因为这些输入数组每个都只有一个元素:第一个数组中的
dict_keys(['a', 'b'])
和第二个数组中的
dict_keys(['b', 'c'])
。这些是不同的对象,因此它们的交集是一个空集。

© www.soinside.com 2019 - 2024. All rights reserved.