import numpy
data = numpy.random.randint(0, 10, (6,8))
test = set(numpy.random.randint(0, 10, 5))
Run Code Online (Sandbox Code Playgroud)
我想要一个表达式,其值是一个布尔数组,具有相同的形状data(或者,至少可以重新整形为相同的形状),告诉我相应的术语data是否在set.
例如,如果我想知道哪些元素data严格小于6,我可以使用单个矢量化表达式,
a = data < 6
Run Code Online (Sandbox Code Playgroud)
计算6x8布尔ndarray.相反,当我尝试一个明显等效的布尔表达式时
b = data in test
Run Code Online (Sandbox Code Playgroud)
我得到的是一个例外:
TypeError: unhashable type: 'numpy.ndarray'
Run Code Online (Sandbox Code Playgroud)
编辑:下面的可能性#4给出了错误的结果,感谢hpaulj和Divakar让我走上正轨.
在这里我比较四种不同的可能性
np.in1d(data, np.hstack(test)).np.in1d(data, np.array(list(test))).np.in1d(data, test).这是Ipython会话,略微编辑以避免空行
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
Run Code Online (Sandbox Code Playgroud)
In [9]: %timeit np.in1d(data, test)
1000 loops, best of 3: 687 µs per loop
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
Run Code Online (Sandbox Code Playgroud)
In [17]: %timeit np.in1d(data, test)
10 loops, best of 3: 67.9 ms per loop
In [18]:
Run Code Online (Sandbox Code Playgroud)
(现在)匿名海报的回答给出了更好的时间.
事实证明,匿名海报有充分理由删除他们的答案,结果是错误的!
正如hpaulj所评论的,在文档中in1d有一个警告,反对使用a set作为第二个参数,但如果计算结果可能是错误的,我会更好地明确失败.
也就是说,使用的解决方案numpy.fromiter()具有最佳数字......
我假设您正在寻找一个布尔数组来检测数组中set元素的存在data.要做到这一点,就可以提取从元件set带np.hstack,然后使用np.in1d检测的存在任何元件从set在每个位置data,给人的尺寸相同的一个布尔值阵列data.由于np.in1d在处理之前使输入变平,因此作为最后一步,我们需要将输出np.in1d重新2D整形为其原始形状.因此,最终的实施将是 -
np.in1d(data,np.hstack(test)).reshape(data.shape)
Run Code Online (Sandbox Code Playgroud)
样品运行 -
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
192 次 |
| 最近记录: |