gpt4 book ai didi

python - 使用numpy在数组中创建匹配行的二进制数组?

转载 作者:行者123 更新时间:2023-11-28 17:12:18 24 4
gpt4 key购买 nike

我想创建一个二进制数组来显示 numpy 数组中的所有匹配行。在这种情况下,如果原始矩阵中的行 i 相同,则新矩阵的下列 j 中的第 i 个索引将对应于 1作为原始矩阵中的 j 行。

例如,如果矩阵如下所示:

[ [a b c]
[d e f]
[a b c]
[d e f]]

我要输出的是

[[1 0 1 0]
[0 1 0 1]
[1 0 1 0]
[0 1 0 1]]

现在,我正在通过这样的循环来完成它:

same_mat=np.empty((agents,agents))
for i in range(matrix.shape[0]):
same_mat[:,i]=np.all(matrix[i,:]==matrix,axis=1)

但是,这很慢,因为它必须单独遍历原始矩阵中的每一行以生成新矩阵中的每一列。有什么矢量化的方法可以更快地做到这一点吗?

谢谢

最佳答案

方法 #1: 我们可以简单地扩展数组的两个 3D 版本并进行比较,从而让 broadcasting施展魔法 -

(arr[:,None] == arr).all(2).astype(int)

sample 运行-

In [19]: a,b,c,d,e,f = 4,7,3,1,8,2
...: arr = np.array([
...: [a, b, c],
...: [d ,e, f],
...: [a ,b, c],
...: [d ,e, f]])
...:

In [20]: arr
Out[20]:
array([[4, 7, 3],
[1, 8, 2],
[4, 7, 3],
[1, 8, 2]])

In [21]: (arr[:,None] == arr).all(2).astype(int)
Out[21]:
array([[1, 0, 1, 0],
[0, 1, 0, 1],
[1, 0, 1, 0],
[0, 1, 0, 1]])

方法 #2: 使用 views 的内存高效方法,因为我们将每一行减少到一个 value,然后执行 broadcasted -比较 -

# https://stackoverflow.com/a/44999009/ @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()

arr1D = view1D(arr)
out = (arr1D[:,None] == arr1D).astype(int)

方法#3:出于对内置函数的热爱,这里有另一个在理论上与前一个相似的方法,但使用了np.unique。具有新的 axis 功能 -

ids = np.unique(arr, axis=0, return_inverse=1)[1]
out = (ids[:,None] == ids).astype(int)

方法 #4:另一种根据每一行在其他行中的唯一性来标记每一行的方法是将每一行视为 2D 网格上的线性索引等价物,为我们提供了一种更高效的方式来获取 ids -

ids = arr.dot((arr.max()-arr.min()+1)**np.arange(arr.shape[1]))
out = (ids[:,None] == ids).astype(int)

如果我们保证有正数,请跳过arr.min()

我们在这里需要小心,因为数字的巨大变化或列数充足会导致溢出。因此,在使用这种方法时请记住这些。

额外内容

为了获得最大性能,使用 uint8 作为输出数据类型,这看起来不错,因为我们只需要在 0s1s 中输出,如下面的时间所示 -

In [41]: bool_arr = np.random.rand(100,100)>0.5

In [42]: %timeit bool_arr.astype(int)
...: %timeit bool_arr.astype(np.uint8)
...:
100000 loops, best of 3: 4.15 µs per loop
1000000 loops, best of 3: 897 ns per loop

In [43]: bool_arr = np.random.rand(5000,5000)>0.5

In [44]: %timeit bool_arr.astype(int)
...: %timeit bool_arr.astype(np.uint8)
...:
10 loops, best of 3: 21 ms per loop
100 loops, best of 3: 3.16 ms per loop

关于python - 使用numpy在数组中创建匹配行的二进制数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46796117/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com