use*_*121 3 python numpy matrix multidimensional-array
我有一个2D numpy数组,其中包含'n'个唯一值.我想生成一个二进制矩阵,其中所有值都替换为"零",并且我指定的值被指定为"一".
例如,我有一个如下数组,我想要为35的所有实例分配'one':
array([[12, 35, 12, 26],
[35, 35, 12, 26]])
Run Code Online (Sandbox Code Playgroud)
我想获得以下输出:
array([[0, 1, 0, 0],
[1, 1, 0, 0]])
Run Code Online (Sandbox Code Playgroud)
在Python中最有效的方法是什么?
import numpy as np
x = np.array([[12, 35, 12, 26], [35, 35, 12, 26]])
(x == 35).astype(int)
Run Code Online (Sandbox Code Playgroud)
会给你:
array([[0, 1, 0, 0],
[1, 1, 0, 0]])
Run Code Online (Sandbox Code Playgroud)
numpy中的==运算符执行逐元素比较,当将布尔值转换为整数时,True编码为1,False编码为0.
与所有其他解决方案相比,一种更优雅的方法是仅使用 np.isin()
>>> arr
array([[12, 35, 12, 26],
[35, 35, 12, 26]])
# get the result as binary matrix
>>> np.isin(arr, 35).astype(np.uint8)
array([[0, 1, 0, 0],
[1, 1, 0, 0]])
Run Code Online (Sandbox Code Playgroud)
np.isin()会返回一个布尔型掩码,其True值带有35原始数组和False其他位置中给定元素(此处)的位置。
另一个变体是使用np.asarray()数据类型强制转换布尔结果np.uint8以提高速度:
In [18]: np.asarray(np.isin(x, 35), dtype=np.uint8)
Out[18]:
array([[0, 1, 0, 0],
[1, 1, 0, 0]], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)
通过将布尔结果显式转换为uint8,我们可以获得更好的3倍以上的性能。(感谢@Divakar指出这一点!)请参见以下时序:
# setup (large) input array
In [3]: x = np.arange(25000000)
In [4]: x[0] = 35
In [5]: x[1000000] = 35
In [6]: x[2000000] = 35
In [7]: x[-1] = 35
In [8]: x = x.reshape((5000, 5000))
# timings
In [20]: %timeit np.where(x==35, 1, 0)
427 ms ± 25.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [21]: %timeit (x == 35) + 0
450 ms ± 72 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [22]: %timeit (x == 35).astype(np.uint8)
126 ms ± 37.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# the fastest choice to go for!
In [23]: %timeit np.isin(x, 35).astype(np.uint8)
115 ms ± 2.21 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [24]: %timeit np.asarray(np.isin(x, 35), dtype=np.uint8)
117 ms ± 2.91 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)
如果您要使用真正的战马,请numexpr在中使用:
In [8]: import numexpr as ne
In [9]: %timeit ne.evaluate("x==35").astype(np.uint8)
23 ms ± 2.69 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)
这是ca。使用基于NumPy的计算,速度比最慢的方法快20倍。
最后,如果视图还可以,我们可以使用NumPy方法本身获得如此疯狂的加速。
In [13]: %timeit (x == 35).view(np.uint8)
20.1 ms ± 93.2 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [15]: %timeit np.isin(x, 35).view(np.uint8)
30.2 ms ± 1.16 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2354 次 |
| 最近记录: |