在numpy矩阵中交换零 [英] Swap zeros in numpy matrix

查看:141
本文介绍了在numpy矩阵中交换零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似的numpy矩阵:

I have a numpy matrix like so:

array([[2,  1, 23, 32],
       [34, 3, 3, 0],
       [3, 33, 0, 0],
       [32, 0, 0, 0]], dtype=int32)

现在,我想将所有数字向右移动,然后将零向左交换,就像这样:

Now I want to shift all the numbers to the right and swap the zeros to the left like so:

array([[2, 1,  23, 32],
       [0, 34, 3,  3],
       [0, 0,  3,  33],
       [0, 0,  0,  32]], dtype=int32)

是否可以通过numpy,pandas或scikit-learn的api方法来作为一种简短的pythonic方法?

Is there as a short pythonic way of doing this, perhaps with api method from numpy, pandas or scikit-learn?

推荐答案

这是一种使用

Here's a vectorized approach with masking -

valid_mask = a!=0
flipped_mask = valid_mask.sum(1,keepdims=1) > np.arange(a.shape[1]-1,-1,-1)
a[flipped_mask] = a[valid_mask]
a[~flipped_mask] = 0

样品运行-

In [90]: a
Out[90]: 
array([[ 2,  1, 23, 32],
       [34,  0,  3,  0],  # <== Added a zero in between for variety
       [ 3, 33,  0,  0],
       [32,  0,  0,  0]])

# After code run -

In [92]: a
Out[92]: 
array([[ 2,  1, 23, 32],
       [ 0,  0, 34,  3],
       [ 0,  0,  3, 33],
       [ 0,  0,  0, 32]])

再进行一次通用示例运行-

One more generic sample run -

In [94]: a
Out[94]: 
array([[1, 1, 2, 3, 1, 0, 3, 0, 2, 1],
       [2, 1, 0, 1, 2, 0, 1, 3, 1, 1],
       [1, 2, 0, 3, 0, 3, 2, 0, 2, 2]])

# After code run -

In [96]: a
Out[96]: 
array([[0, 0, 1, 1, 2, 3, 1, 3, 2, 1],
       [0, 0, 2, 1, 1, 2, 1, 3, 1, 1],
       [0, 0, 0, 1, 2, 3, 3, 2, 2, 2]])

运行时测试

适用于一般情况的方法-

Approaches that work on generic cases -

# Proposed in this post
def masking_based(a):
    valid_mask = a!=0
    flipped_mask = valid_mask.sum(1,keepdims=1) > np.arange(a.shape[1]-1,-1,-1)
    a[flipped_mask] = a[valid_mask]
    a[~flipped_mask] = 0
    return a

# @Psidom's soln            
def sort_based(a):
    return a[np.arange(a.shape[0])[:, None], (a != 0).argsort(1, kind="mergesort")]

时间-

In [205]: a = np.random.randint(0,4,(1000,1000))

In [206]: %timeit sort_based(a)
10 loops, best of 3: 30.8 ms per loop

In [207]: %timeit masking_based(a)
100 loops, best of 3: 6.46 ms per loop

In [208]: a = np.random.randint(0,4,(5000,5000))

In [209]: %timeit sort_based(a)
1 loops, best of 3: 961 ms per loop

In [210]: %timeit masking_based(a)
1 loops, best of 3: 151 ms per loop

这篇关于在numpy矩阵中交换零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆