基于另一个二进制d的Numpy子集矩阵

2024-06-02 07:31:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个n x m矩阵X和一个n x p矩阵Y,其中Y是二进制数据。最后,我想要一个p x n矩阵Z,其中Z的列是X的列子集的函数,它对应于Y中的1。你知道吗

例如

>>> X
array([[1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]])
>>> Y
array([[1, 0],
    [1, 0],
    [0, 1]])
n_x,m = X.shape
n_y,p = Y.shape
Z = np.zeros([p, n_x])
for i in range(n_x):
    col = X[:,[i]]
    for j in range(p):
        #this is where I subset col with Y[:,[j]]
        Z[j][i] = my_func(subsetted_column)

迭代将产生

i=0, j=0: subsetted_column = [[1],[4]]
i=0, j=1: subsetted_column = [[7]]
i=1, j=0: subsetted_column = [[2],[5]]
i=1, j=1: subsetted_column = [[8]]
i=2, j=0: subsetted_column = [[3],[6]]
i=2, j=1: subsetted_column = [[9]]

我假设有某种方法可以在单个列表中实现嵌套循环。函数my_func也需要很长的时间,所以最好以某种方式并行化。你知道吗

编辑:我可以做

for i in range(n_x):
    for j in range(p):
        subsetted_column = np.trim_zeros(np.multiply(X[:,i], Y[:,j]))
        Z[j][i] = my_func(subsetted_column)

但我仍然相信有一个更简单的解决办法


Tags: 函数informynp二进制zerosrange
2条回答

它可能有助于在预处理循环中执行子集设置

In [112]: xs = [X[y,:] for y in Y.astype(bool).T]
In [113]: xs
Out[113]: 
[array([[1, 2, 3],
        [4, 5, 6]]), 
 array([[7, 8, 9]])]

.T用于迭代列表理解中的列;bool允许“屏蔽”选择)

比如说,对于子集,my_func取轴上的平均值=0

In [116]: [np.mean(s, axis=0) for s in xs]
Out[116]: [array([ 2.5,  3.5,  4.5]), array([ 7.,  8.,  9.])]
In [117]: np.array(_)
Out[117]: 
array([[ 2.5,  3.5,  4.5],
       [ 7. ,  8. ,  9. ]])

我可以把它组合成一个循环,但更难思考:

np.array([np.mean(X[y,:],axis=0) for y in Y.astype(bool).T])

有了这个xs列表,您可以像np.mean(xs[i], axis=0)那样,集中精力将my_func有效地应用于xs[i]的所有列。你知道吗

这个平均数的双环版本

In [121]: p=np.zeros((2,3))
In [122]: for i in range(2):
     ...:     for j in range(3):
     ...:         p[i,j] = np.mean(xs[i][:,j])
     ...:         
In [123]: p
Out[123]: 
array([[ 2.5,  3.5,  4.5],
       [ 7. ,  8. ,  9. ]])

等价双表理解

In [125]: [[np.mean(i) for i in j.T] for j in xs]
Out[125]: [[2.5, 3.5, 4.5], [7.0, 8.0, 9.0]]

这是你想要的吗?你知道吗

import numpy as np

N, M, P = 4, 3, 2

a = np.random.random((N, M))
b = np.random.randint(2, size=(N, P)).astype(bool)

your_func = lambda x: x # insert proper function here
flat = [your_func(ai[bj]) for bj in b.T for ai in a.T]

out = np.empty((P, M), dtype=object)
out.ravel()[:] = flat
print(a)
print(b)
print(out)

备注:

  • 将掩蔽数组转换为dtype bool最简单,因为这样可以使用逻辑索引。你知道吗
  • 如果your_func只返回一个数字,最好不要将dtype=object用于out。你知道吗
  • 如果你想并行,列表理解也许不是最好的办法,但我不是这方面的专家。只是循环看起来像是一个明显的并行化目标,因为迭代的顺序是不相关的。你知道吗

样本输出:

[[ 0.62739382  0.85774837  0.81958524]
 [ 0.99690996  0.71202879  0.97636715]
 [ 0.89235107  0.91739852  0.39537849]
 [ 0.0413107   0.11662271  0.72419308]]
[[False  True]
 [ True  True]
 [False False]
 [ True  True]]
[[array([ 0.99690996,  0.0413107 ]) array([ 0.71202879,  0.11662271])
  array([ 0.97636715,  0.72419308])]
 [array([ 0.62739382,  0.99690996,  0.0413107 ])
  array([ 0.85774837,  0.71202879,  0.11662271])
  array([ 0.81958524,  0.97636715,  0.72419308])]]

相关问题 更多 >