假设我有一个NumPy数组如下:我的原始数组是50K X8.5K大小。这是样本
array([[ 1. , 2. , 3. ],
[ 1. , 0.5, 2. ],
[ 2. , 3. , 1. ]])
现在我想要的是,对于每一列,只保留前K个值(让我们将K取为2)并将其他列重新编码为零。
所以我期待的输出是这样的:
array([[ 1., 2., 3.],
[ 1., 0., 2.],
[ 2., 3., 0.]])
所以基本上如果我们看到,我们会按降序对每个列值进行排序,然后检查该列的每个值是否不在该列的k-最大值之间,然后将该值重新编码为零
我尝试过这样的事情,但是却出错了
for x in range(e.shape[1]):
e[:,x]=map(np.where(lambda x: x in e[:,x][::-1][:2], x, 0), e[:,x])
2
3 for x in range(e.shape[1]):
----> 4 e[:,x]=map(np.where(lambda x: x in e[:,x][::-1][:2], x, 0), e[:,x])
5
TypeError: 'numpy.ndarray' object is not callable
目前我也在为每一列进行迭代。任何解决方案都可以快速工作,因为我喜欢50K行和8K列,因此对每列进行迭代,然后对于每列执行该列中每个值的映射将是耗时的。
请指教。
答案 0 :(得分:1)
关注这些大型阵列的性能,这是解决它的矢量化方法 -
K = 2 # Select top K values along each column
# Sort A, store the argsort for later usage
sidx = np.argsort(A,axis=0)
sA = A[sidx,np.arange(A.shape[1])]
# Perform differentiation along rows and look for non-zero differentiations
df = np.diff(sA,axis=0)!=0
# Perform cumulative summation along rows from bottom upwards.
# Thus, summations < K should give us a mask of valid ones that are to
# be kept per column. Use this mask to set rest as zeros in sorted array.
mask = (df[::-1].cumsum(0)<K)[::-1]
sA[:-1] *=mask
# Finally revert back to unsorted order by using sorted indices sidx
out = sA[sidx.argsort(0),np.arange(sA.shape[1])]
请注意,为了提升效果,np.argsort
可以替换为np.argpartition
。
样本输入,输出 -
In [343]: A
Out[343]:
array([[106, 106, 102],
[105, 101, 104],
[106, 107, 101],
[107, 103, 106],
[106, 105, 108],
[106, 104, 105],
[107, 101, 101],
[105, 103, 102],
[104, 102, 106],
[104, 106, 101]])
In [344]: out
Out[344]:
array([[106, 106, 0],
[ 0, 0, 0],
[106, 107, 0],
[107, 0, 106],
[106, 0, 108],
[106, 0, 0],
[107, 0, 0],
[ 0, 0, 0],
[ 0, 0, 106],
[ 0, 106, 0]])
答案 1 :(得分:0)
这应该可以帮助你:
def rwhere(a, b, p, k):
if p >= len(b) or p >= k:
return 0
else:
return np.where(a == b[p], b[p], rwhere(a, b, p + 1, k))
def codek(a, k):
b = a.copy()
b.sort(0)
b = b[::-1]
return rwhere(a, b, 0, k)
codek(a, 2)
array([[ 1., 2., 3.],
[ 1., 0., 2.],
[ 2., 3., 0.]])
答案 2 :(得分:0)
确定。我只知道我的代码中存在什么问题。 where子句应该是lambda函数的返回条件。以下工作正常。
array([[ 1. , 2. , 3. ],
[ 1. , 0.5, 2. ],
[ 2. , 3. , 1. ]])
e=copy.deepcopy(a)
for y in range(e.shape[1]):
e[:,y]=map(lambda x: np.where(x in np.sort(a[:,y])[::-1][:2],x, 0), e[:,y])
array([[ 1., 2., 3.],
[ 1., 0., 2.],
[ 2., 3., 0.]])
In [297]:
而不是2我可以将它保持为K,并且应该也可以正常工作。