避免列切片数组进行计算

时间:2017-05-18 14:27:17

标签: python numpy

import numpy as np
Xs = np.array([[1,3,3,4,5,7], [2,4,5,1,1,6], [5,5,6,4,3,2]]).T
groupIDs = np.array([10,10,20,20,30,30])
p = np.array([0.5, 0.5, 0.25, 0.75, 1, 0])
_,idx,tags = np.unique(groupIDs, return_index=1, return_inverse=1)
print(Xs)
[[1 2 5]
 [3 4 5]
 [3 5 6]
 [4 1 4]
 [5 1 3]
 [7 6 2]]

我正在尝试使用每个组pX之间的产品总和创建一个新表,每列。我能想到的唯一方法就是

new = np.empty((6,3))
for i in range(3):
    new[:,i] = np.add.reduceat((p * Xs[:,i]),idx)[tags] 
print(new)
[[ 2.    3.    5.  ]
 [ 2.    3.    5.  ]
 [ 3.75  2.    4.5 ]
 [ 3.75  2.    4.5 ]
 [ 5.    1.    3.  ]
 [ 5.    1.    3.  ]]

我正在努力调整自己的思维,以'向量'思考,以便通过避免循环使我的大型数据集(包括数千个xs)更快地工作(希望)。请给我任何建议。

2 个答案:

答案 0 :(得分:2)

这是没有np.unique的另一个选项(假设相同的groupID已经排序在一起):

def diff():
    idx = np.concatenate(([0], np.flatnonzero(np.diff(groupIDs))+1))
    inv = np.repeat(pd.np.arange(idx.size), np.diff(np.concatenate((idx, [groupIDs.size]))))
    return np.add.reduceat((Xs.T*p), idx, axis=1).T[inv]

diff()
#array([[ 2.  ,  3.  ,  5.  ],
#       [ 2.  ,  3.  ,  5.  ],
#       [ 3.75,  2.  ,  4.5 ],
#       [ 3.75,  2.  ,  4.5 ],
#       [ 5.  ,  1.  ,  3.  ],
#       [ 5.  ,  1.  ,  3.  ]])

答案 1 :(得分:2)

import numpy as np
Xs = np.array([[1,3,3,4,5,7], [2,4,5,1,1,6], [5,5,6,4,3,2]])
groupIDs = np.array([10,10,20,20,30,30])
p = np.array([0.5, 0.5, 0.25, 0.75, 1, 0])
_,idx,tags = np.unique(groupIDs, return_index=1, return_inverse=1)

print np.add.reduceat((p*Xs).T, idx)[tags]

无需使用for。转置一些矩阵就足够了,检查最后一行。

我在Xs的声明中移除了转置。但如果你真的需要它,你必须在最后一行添加一个((p*Xs.T).T