2017-03-01 185 views
1

我有1000行和2列的numpy的阵列:排名2D 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]] 

明显看出,此阵列在通过柱1.我想由列0和按升序降序排序分配秩该阵列,使得重复行(两行或更多行的两个列值是相等的)中的每一行具有相同的秩和插入秩为塔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]] 

什么是最有效的方法来实现这个?

+1

那么,你可以写下预期的o/p吗? – Divakar

+0

你如何定义:1.重复行; 2.一排的排名; ? – heltonbiker

+0

@Divakar我已经添加了预期的输出。 –

回答

2

对于排序后的数组,如给定样品中,它很容易 -

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排名和我们打算用cumumlative总和为这个增量排名,让我们追加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.  ]]) 
+0

嘿,它像一个魅力工作!你是'pyGod'。哈哈哈...你可以请解释一下这个代码是如何工作的? –

+0

@VaibhavAgarwal与样本一起附加几个解释。 – Divakar