【问题标题】:Ranking 2D Numpy array排名二维 Numpy 数组
【发布时间】:2017-03-01 16:35:31
【问题描述】:

我有一个 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]]

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

【问题讨论】:

  • 那么,你能写下预期的 o/p 吗?
  • 如何定义:1.重复行; 2. 排位; ?
  • @Divakar 我添加了预期的输出。

标签: python arrays numpy ranking


【解决方案1】:

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

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) 获取连续行之间不等式的掩码。这里的想法是,由于数组已排序,因此重复的行将在两列中具有相同的元素。因此,由于两列之间的不等式,我们将有一个 1D 掩码,但一个元素比原始数组中的总行数少一个元素,因为我们使用切片并保留一个元素:

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,然后使用@ 987654328@ 给我们预期的排名:

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.        ]])

【讨论】:

  • 嘿,它就像一个魅力!你是pyGod。哈哈哈......你能解释一下这段代码是如何工作的吗??
  • @VaibhavAgarwal 添加一些解释和示例。
猜你喜欢
  • 1970-01-01
  • 2020-07-30
  • 2021-01-19
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-10
  • 1970-01-01
相关资源
最近更新 更多