python - 二维 Numpy 数组排名

标签 python arrays numpy ranking

我有一个 1000 行 2 列的 numpy 数组:

[[ 0.76        1.28947368]
 [ 0.7         0.97142857]
 [ 0.7         1.48571429]
 [ 0.68        1.11764706]
 [ 0.68        1.23529412]
 [ 0.68        1.41176471]
 [ 0.68        1.41176471]
 [ 0.68        1.44117647]
 [ 0.66        0.78787879]
 [ 0.66        1.03030303]
 [ 0.66        1.09090909]
 [ 0.66        1.15151515]
 [ 0.66        1.15151515]
 [ 0.66        1.21212121]
 [ 0.66        1.24242424]]

很明显,该数组按第 0 列降序排序,按第 1 列升序排序。我想为该数组的每一行分配排名,以便重复的行(两行或更多行的两列中的值都是equal) 具有相同的排名并插入排名作为第 2 列。

预期输出:

     [[0.76        1.28947368  1]
     [ 0.7         0.97142857  2]
     [ 0.7         1.48571429  3]
     [ 0.68        1.11764706  4]
     [ 0.68        1.23529412  5]
     [ 0.68        1.41176471  6]
     [ 0.68        1.41176471  6]  # as this row is duplicate of row above it
     [ 0.68        1.44117647  7]
     [ 0.66        0.78787879  8]
     [ 0.66        1.03030303  9]
     [ 0.66        1.09090909  10]
     [ 0.66        1.15151515  11]
     [ 0.66        1.15151515  11] # as this row is duplicate of row above it
     [ 0.66        1.21212121  12]
     [ 0.66        1.24242424  13]]

实现这一目标最有效的方法是什么?

最佳答案

对于排序数组,就像给定的示例一样,很容易 -

rank = np.r_[True, (a[1:] != a[:-1]).any(1)].cumsum()
out = np.column_stack(( a, rank ))

作为 (a[1:] != a[:-1]).any(1) 的替代方案,我们可以使用以下内容来提高性能:

(a[1:,0] != a[:-1,0]) | (a[1:,1] != a[:-1,1])

分步运行示例

1) 输入数组:

In [70]: a
Out[70]: 
array([[ 0.76      ,  1.28947368],
       [ 0.68      ,  1.41176471],
       [ 0.68      ,  1.41176471],
       [ 0.68      ,  1.44117647],
       [ 0.66      ,  1.09090909],
       [ 0.66      ,  1.15151515],
       [ 0.66      ,  1.15151515],
       [ 0.66      ,  1.24242424]])

2) 获取连续行之间不等式的掩码。这里的想法是,由于数组已排序,因此重复的行在两列中将具有相同的元素。因此,由于两列之间存在不等式,我们将得到一个一维掩码,但一个元素比原始数组中的总行数少,因为我们使用了切片时留下了一个元素:

In [71]: a[1:] != a[:-1]
Out[71]: 
array([[ True,  True],
       [False, False],
       [False,  True],
       [ True,  True],
       [False,  True],
       [False, False],
       [False,  True]], dtype=bool)

In [72]: (a[1:] != a[:-1]).any(1)
Out[72]: array([ True, False,  True,  True,  True, False,  True], dtype=bool)

现在,为了补偿少一元素,并且由于我们需要从 1 开始排名,并且我们打算使用累积求和来进行此增量排名,因此让我们附加一个 1 在开始,然后使用 cumsum 给我们预期的排名:

In [75]: np.r_[True, (a[1:] != a[:-1]).any(1)]
Out[75]: array([ True,  True, False,  True,  True,  True, False,  True], dtype=bool)

In [76]: np.r_[True, (a[1:] != a[:-1]).any(1)].cumsum()
Out[76]: array([1, 2, 2, 3, 4, 5, 5, 6])

为了直观地验证,这里是堆叠输出:

In [77]: np.column_stack(( a, _ ))
Out[77]: 
array([[ 0.76      ,  1.28947368,  1.        ],
       [ 0.68      ,  1.41176471,  2.        ],
       [ 0.68      ,  1.41176471,  2.        ],
       [ 0.68      ,  1.44117647,  3.        ],
       [ 0.66      ,  1.09090909,  4.        ],
       [ 0.66      ,  1.15151515,  5.        ],
       [ 0.66      ,  1.15151515,  5.        ],
       [ 0.66      ,  1.24242424,  6.        ]])

关于python - 二维 Numpy 数组排名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42537153/

相关文章:

python - 在 KafkaUtils.createstream() 中使用 "topics"参数的正确方法是什么?

ruby-on-rails - 如何使用表单填充 Rails 4 模型中的序列化数组?

javascript - 从本地读取txt文件放入数组并数组放入<select>

python - 在哪里可以找到 numpy 百分位数的源代码

python - 值错误 : NumPy boolean array indexing assignment cannot assign 0 input values to the N output values where the mask is true

python - 将 ctypes int** 转换为 numpy 二维数组

python - mysql 连接器不显示插入的结果

python - 奇怪的 Python 函数作用域行为

php - 使用 CodeIgniter 在表中显示数组结果时出现问题

python - numpy 数组按向量划分列