Python中每行和每列的重复顺序

时间:2016-08-29 00:28:33

标签: python numpy

我一直在试图计算每行重复的顺序而且无法做到。好。让我们考虑一个大小为(2, 11, 10)

的ndarray
a = np.array([
    [
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [1, 1, 0, 0, 0, 1, 1, 1, 0, 0],
        [0, 1, 0, 0, 0, 1, 0, 0, 1, 0],
        [1, 1, 0, 0, 1, 1, 1, 1, 0, 0],
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
        [1, 0, 0, 1, 0, 1, 1, 1, 0, 0],
        [1, 1, 0, 1, 1, 0, 1, 1, 0, 0],
        [0, 1, 1, 1, 0, 0, 1, 1, 0, 1],
        [1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
        [0, 0, 1, 1, 0, 1, 0, 0, 1, 1],
        [0, 1, 1, 1, 0, 0, 1, 1, 0, 1]
    ],
    [
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 0, 0, 1, 0, 0, 0, 1, 1],
        [0, 1, 0, 1, 0, 0, 0, 1, 0, 0],
        [1, 1, 0, 1, 0, 1, 1, 1, 0, 0],
        [1, 1, 0, 1, 0, 0, 0, 0, 0, 0],
        [1, 1, 1, 0, 0, 0, 1, 1, 0, 0],
        [1, 0, 0, 0, 1, 1, 0, 0, 1, 1],
        [1, 1, 1, 0, 0, 1, 1, 1, 0, 1],
        [1, 0, 0, 1, 1, 0, 1, 0, 1, 0],
        [1, 0, 0, 0, 0, 0, 1, 0, 0, 0],
        [1, 1, 1, 0, 0, 1, 1, 1, 0, 1]
    ]
])

我想要的是根据列获取每行1's的顺序。只要在一行中找到第一个1,订单就会从0开始;如果在此处找到1,则转到第二行,然后订单为1,但如果1已经出现在上一行的列索引中,则忽略它。例如

让我们考虑一下这些清单:

   0  1  2  3  4  5  6  7  8  9   -> column index
0 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], -> no 1's no order here
1 [1, 1, 0, 0, 0, 1, 1, 1, 0, 0], -> order starts at 0
2 [0, 1, 0, 0, 0, 1, 0, 0, 1, 0], -> order starts at 1

在行索引0处没有1因此没有任何反应,在行索引1处,列索引[0,1,5,6,7]中有一些这将等于{{1} }};输出应该是

0

在行索引column order 0 0 1 0 2 - 3 - 4 - 5 0 6 0 7 0 8 - 9 - 处,列索引2处有1,其顺序为[1,5,8];在11被忽略,因为它已经有一个订单5,但对于未知订单,它应该是0;最终的输出应该是

1

我尝试将Numpy的column order 0 0 1 0 2 - 3 - 4 - 5 0 6 0 7 0 8 1 9 - 方法用于索引值;像这样的东西

np.where

我不知道下一步该做什么。有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:1)

显然,基于对问题的评论和此答案的早期版本,期望的结果是找到"密集排名"每列中第一个1的行索引。 (请参阅scipy.stats.rankdata的文档字符串,了解"密集排名"的含义。)结果可以使用.argmax()方法和scipy.stats.rankdata的组合找到。

这是一个计算二维数组顺序的函数。问题没有定义当列全为零时应该发生什么; order为该列指定值-1。

from scipy.stats import rankdata

def order(x):
    result = x.argmax(axis=0)
    result[(x == 0).all(axis=0)] = -1
    rank = rankdata(result, method='dense') - 1 - np.any(result < 0)
    return rank

例如,这是数组y

In [71]: y
Out[71]: 
array([[0, 1, 0, 0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 0],
       [1, 1, 1, 0, 1, 1, 0, 0],
       [1, 0, 1, 1, 1, 1, 0, 0],
       [1, 0, 0, 0, 1, 1, 1, 0]])

In [72]: order(y)
Out[72]: array([ 1,  0,  1,  2,  0,  0,  3, -1])

这里是问题中的数组a

In [73]: a
Out[73]: 
array([[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [1, 1, 0, 0, 0, 1, 1, 1, 0, 0],
        [0, 1, 0, 0, 0, 1, 0, 0, 1, 0],
        [1, 1, 0, 0, 1, 1, 1, 1, 0, 0],
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
        [1, 0, 0, 1, 0, 1, 1, 1, 0, 0],
        [1, 1, 0, 1, 1, 0, 1, 1, 0, 0],
        [0, 1, 1, 1, 0, 0, 1, 1, 0, 1],
        [1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
        [0, 0, 1, 1, 0, 1, 0, 0, 1, 1],
        [0, 1, 1, 1, 0, 0, 1, 1, 0, 1]],

       [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 0, 0, 1, 0, 0, 0, 1, 1],
        [0, 1, 0, 1, 0, 0, 0, 1, 0, 0],
        [1, 1, 0, 1, 0, 1, 1, 1, 0, 0],
        [1, 1, 0, 1, 0, 0, 0, 0, 0, 0],
        [1, 1, 1, 0, 0, 0, 1, 1, 0, 0],
        [1, 0, 0, 0, 1, 1, 0, 0, 1, 1],
        [1, 1, 1, 0, 0, 1, 1, 1, 0, 1],
        [1, 0, 0, 1, 1, 0, 1, 0, 1, 0],
        [1, 0, 0, 0, 0, 0, 1, 0, 0, 0],
        [1, 1, 1, 0, 0, 1, 1, 1, 0, 1]]])

函数order()需要一个二维数组,所以我们必须使用一个循环来获取a中每个子数组的顺序:

In [74]: np.array([order(m) for m in a])
Out[74]: 
array([[0, 0, 3, 3, 2, 0, 0, 0, 1, 4],
       [2, 0, 3, 1, 0, 2, 2, 1, 0, 0]])