【问题标题】:Python, Numpy, replacing second max value with 1, others with 0Python,Numpy,用 1 替换第二个最大值,用 0 替换其他最大值
【发布时间】:2018-02-16 07:47:27
【问题描述】:

浏览 Internet 并没有为我的问题提供任何结果。我有这样的数组:

y=  [[ 2.63321579e-16   9.99986649e-01   2.90973702e-32   9.93230242e-06
        1.56965105e-30   1.63843623e-07   8.52455060e-22   0.00000000e+00
        5.65191413e-27   0.00000000e+00   3.20573202e-25   0.00000000e+00
        3.33013941e-06   0.00000000e+00   8.01929339e-22   2.14279644e-26
        0.00000000e+00   4.32979661e-08   1.01565330e-29   0.00000000e+00
        0.00000000e+00   4.52104604e-11]
     [  0.00000000e+00   1.57162935e-01   0.00000000e+00   0.00000000e+00
        0.00000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00
        0.00000000e+00   8.42837036e-01   3.78666698e-08   0.00000000e+00
        0.00000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00
        0.00000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00
        0.00000000e+00   0.00000000e+00]]

我想做的是用“1”替换每行的第二个最大值,用“0”替换其中的任何其他值。我知道如何使用最大值,首先创建 zeros_like 数组,然后用 1 替换最大值。因此,方法是:

x = np.zeros_like(y)
x[np.arange(len(y)), y.argmax(1)] = 1

但是第二个最大值会如何呢?期望的输出应该是这样的:

y=  [[ 0 0 0 **1** 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]   
     [ 0 **1** 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]

我可以获得第二个最大值,但替换它会导致我的问题。

【问题讨论】:

标签: python numpy


【解决方案1】:

这是基于np.argpartition 的一种方法。这是为了提高性能,因为它不需要对一行中的所有元素进行排序,因为它只是分成由第 n 个最大元素位置分隔的两个部分。因此,np.argpartition(a,-n, axis=1)[:,-n] 将为我们提供每行的 n-th 最大元素位置。所以,解决方案很简单 -

def n_largest_setarr(a, n=2):
    # a : Input array
    # n : We want n-max element position to be set to 1
    out = np.zeros_like(a)
    out[np.arange(len(a)), np.argpartition(a,-n, axis=1)[:,-n]] = 1
    return out

示例运行 -

# Input array
In [68]: a
Out[68]: 
array([[222, 460, 240, 846, 997, 923, 327, 492],
       [135, 178, 882, 345, 827, 402, 837, 812],
       [820, 838, 666, 143, 122, 727, 323, 249]])

# Use proposed method for various `n` values
In [69]: n_largest_setarr(a, n=2) # second max position set to 1
Out[69]: 
array([[0, 0, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 1, 0],
       [1, 0, 0, 0, 0, 0, 0, 0]])

In [70]: n_largest_setarr(a, n=3) # third max position set to 1
Out[70]: 
array([[0, 0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 0]])

# Use the sorted array to verify values
In [71]: np.sort(a,axis=1)
Out[71]: 
array([[222, 240, 327, 460, 492, 846, 923, 997],
       [135, 178, 345, 402, 812, 827, 837, 882],
       [122, 143, 249, 323, 666, 727, 820, 838]])

【讨论】:

    【解决方案2】:

    首先要找到您要查找的元素,您可以使用argsort 函数获取第二个轴上每个向量值的排序索引列表。

    y = np.random.randn(2,10)
    print(y)
    sorted_idx = np.argsort(y, axis=1)
    nth_element = 2 # Select the nth smallest element of each vector in the second dimension.
    indexes = np.arange(y.shape[0]), np.argsort(y, axis=1)[:, nth_element]
    answer = y[indexes]
    print(answer)
    

    如果您希望获得每个向量中的第 n 个 最大 元素,只需使用 nth_element = -2 代替

    这个测试用例的结果是:

    [[ 2.31754087  1.02712883 -1.06811812  1.2073763  -0.06212109 -0.78401522
      -2.28638542 -0.82081567  1.16203424  0.2775298 ]
     [ 0.30816667  0.81606153  1.32791256  0.65654608  0.36659678  1.29219518
      -0.72793581  0.26714565 -0.69083268 -0.83825039]]
    
    [-0.82081567 -0.69083268]
    

    在此之后,您可以创建一个与初始矩阵形状相同的 zeros 矩阵,并将保存的索引中的相同元素替换为其中的元素。

    zeros = np.zeros(y.shape)
    zeros[indexes] = y[indexes]
    print(zeros)
    

    返回

    [[ 0.          0.          0.          0.          0.          0.          0.
      -0.82081567  0.          0.        ]
     [ 0.          0.          0.          0.          0.          0.          0.
       0.         -0.69083268  0.        ]]
    

    【讨论】:

    • 有人说,它应该给每一行的第二大值,但它没有。
    • 对不起,这是因为argsort 按其值的升序返回索引。我将添加一种在我的答案中获得第二大的方法
    • 基本上我使用反向索引并将nth_element 设置为我想要的最大元素位置的负索引。所以如果你想要第二大的值,你只需设置nth_element = -2
    猜你喜欢
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 2018-11-23
    • 2021-07-28
    相关资源
    最近更新 更多