python - 集合中的数组元素是什么?

标签 python numpy

import numpy
data = numpy.random.randint(0, 10, (6,8))
test = set(numpy.random.randint(0, 10, 5))

我想要一个表达式,其值是一个 bool 数组,具有与 data 相同的形状(或者,至少,可以 reshape 为相同的形状),它告诉我是否相应的项在dataset 中。

例如,如果我想知道 data 的哪些元素严格小于 6,我可以使用一个向量化表达式,

a = data < 6

计算 6x8 bool 值 ndarray。相反,当我尝试一个表面上等价的 bool 表达式时

b = data in test

我得到的是一个异常(exception):

TypeError: unhashable type: 'numpy.ndarray'

附录——对不同的解决方案进行基准测试

编辑:下面的可能性 #4 给出了错误的结果,感谢 hpaulj 和 Divakar 让我走上了正确的道路。

这里我比较了四种不同的可能性,

  1. Divakar 提出的np.in1d(data, np.hstack(test))
  2. hpaulj 的一项提案,np.in1d(data, np.array(list(test)))
  3. hpaulj 的另一个提议,`np.in1d(data, np.fromiter(test, int))。
  4. 作者删除了答案中提出的内容,我不记得作者的名字,np.in1d(data, test)

这是 Ipython session ,略微编辑以避免空行

In [1]: import numpy as np
In [2]: nr, nc = 100, 100
In [3]: top = 3000
In [4]: data = np.random.randint(0, top, (nr, nc))
In [5]: test = set(np.random.randint(0, top, top//3))
In [6]: %timeit np.in1d(data, np.hstack(test))
100 loops, best of 3: 5.65 ms per loop
In [7]: %timeit np.in1d(data, np.array(list(test)))
1000 loops, best of 3: 1.4 ms per loop
In [8]: %timeit np.in1d(data, np.fromiter(test, int))
1000 loops, best of 3: 1.33 ms per loop

在 [9]: %timeit np.in1d(data, test)
1000 次循环,3 次循环中的最佳次数:每次循环 687 微秒

In [10]: nr, nc = 1000, 1000
In [11]: top = 300000
In [12]: data = np.random.randint(0, top, (nr, nc))
In [13]: test = set(np.random.randint(0, top, top//3))
In [14]: %timeit np.in1d(data, np.hstack(test))
1 loop, best of 3: 706 ms per loop
In [15]: %timeit np.in1d(data, np.array(list(test)))
1 loop, best of 3: 269 ms per loop
In [16]: %timeit np.in1d(data, np.fromiter(test, int))
1 loop, best of 3: 274 ms per loop

在 [17]: %timeit np.in1d(data, test)
10 个循环,3 个循环中的最佳:每个循环 67.9 毫秒

In [18]: 

(现在)匿名发布者的回答给出了更好的时间。

事实证明,匿名发布者有充分的理由删除他们的答案,结果是错误的!

正如 hpaulj 评论的那样,在 in1d 的文档中有一条警告不要将 set 用作第二个参数,但我更想要一个明确的如果计算结果可能是错误的,则失败。

也就是说,使用 numpy.fromiter() 的解决方案具有最好的数字...

最佳答案

我假设您正在寻找一个 bool 数组来检测 data 数组中是否存在 set 元素。为此,您可以使用 np.hstackset 中提取元素。然后使用 np.in1d检测 dataeach 位置是否存在 set 中的any 元素,为我们提供相同的 bool 数组大小为 data。由于 np.in1d 在处理之前将输入变平,因此作为最后一步,我们需要将 np.in1d 的输出 reshape 回其原始 2D 形状。因此,最终的实现将是 -

np.in1d(data,np.hstack(test)).reshape(data.shape)

sample 运行-

In [125]: data
Out[125]: 
array([[7, 0, 1, 8, 9, 5, 9, 1],
       [9, 7, 1, 4, 4, 2, 4, 4],
       [0, 4, 9, 6, 6, 3, 5, 9],
       [2, 2, 7, 7, 6, 7, 7, 2],
       [3, 4, 8, 4, 2, 1, 9, 8],
       [9, 0, 8, 1, 6, 1, 3, 5]])

In [126]: test
Out[126]: {3, 4, 6, 7, 9}

In [127]: np.in1d(data,np.hstack(test)).reshape(data.shape)
Out[127]: 
array([[ True, False, False, False,  True, False,  True, False],
       [ True,  True, False,  True,  True, False,  True,  True],
       [False,  True,  True,  True,  True,  True, False,  True],
       [False, False,  True,  True,  True,  True,  True, False],
       [ True,  True, False,  True, False, False,  True, False],
       [ True, False, False, False,  True, False,  True, False]], dtype=bool)

关于python - 集合中的数组元素是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37774990/

相关文章:

python - 使用 pandas 从 CSV 中读取十进制表示形式的 float

python - 根据计算自动选择文件名,然后将其导入到 python 中

python - Pandas 融化以复制值并插入新列

python - 如何更改 Spark Master 的工作目录

python - 使用 Python PIL 捕获 x,y 坐标

python - 文件夹结构和导入

python - 最大总和子列表?

python - 将构造函数添加到 Boost.Python 子类会导致参数不匹配错误

python - Numpy 中的类似分散操作

python - 没有迭代器和/或循环的 Numpy 数组的组合/笛卡尔积