【问题标题】:How to select specific row column pairs in numpy array which have specific value?如何在 numpy 数组中选择具有特定值的特定行列对?
【发布时间】:2017-06-08 10:50:18
【问题描述】:

我正在尝试使用从 0 到 1 的随机数的 numpy 数组:

import numpy as np
x = np.random.random((3,3))

产量

[[ 0.11874238  0.71885484  0.33656161]
 [ 0.69432263  0.25234083  0.66118676]
 [ 0.77542651  0.71230397  0.76212491]]

而且,从这个数组中,我需要值大于 0.3 的行、列组合。所以预期的输出应该是这样的:

(0,1),(0,2),(1,0),(1,2),(2,0),(2,1),(2,2)

为了能够提取item(x[row][column] 的值),并尝试将输出写入文件。我尝试了以下命令:

with open('newfile.txt', 'w') as fd:
    for row in x:
        for item in row:
            if item > 0.3:
                print(item)
                for row in item:
                    for col in item:
                        print(row,column,'\n')
                        fd.write(row,column,'\n')

但是,它会引发错误:

TypeError: 'numpy.float64' object is not iterable

另外,我搜索但找不到如何从 1 而不是 0 开始 numpy 索引。例如,预期的输出将如下所示:

 (1,2),(1,3),(2,1),(2,3),(3,1),(3,2),(3,3)

你知道如何获得这些输出吗?

【问题讨论】:

    标签: arrays numpy random indexing extract


    【解决方案1】:

    在比较掩码上使用np.nonzero/np.where 获取与该条件匹配的前两个轴的索引,然后简单地使用integer array indexing 进行索引-

    r,c = np.nonzero(x>0.3)
    out = x[r,c]
    

    如果您希望获得这些索引的元组列表,zip 这些索引 -

    zip(r,c)
    

    要获取从1 开始的那些,请添加1 然后压缩 -

    zip(r+1,c+1)
    

    Python 3.x 上,您需要用list() 包装它:list(zip(r,c))list(zip(r+1,c+1))

    示例运行 -

    In [9]: x
    Out[9]: 
    array([[ 0.11874238,  0.71885484,  0.33656161],
           [ 0.69432263,  0.25234083,  0.66118676],
           [ 0.77542651,  0.71230397,  0.76212491]])
    
    In [10]: r,c = np.nonzero(x>0.3)
    
    In [14]: zip(r,c)
    Out[14]: [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1), (2, 2)]
    
    In [18]: zip(r+1,c+1)
    Out[18]: [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2), (3, 3)]
    
    In [13]: x[r,c]
    Out[13]: 
    array([ 0.71885484,  0.33656161,  0.69432263,  0.66118676,  0.77542651,
            0.71230397,  0.76212491])
    

    indices 写入文件 -

    使用np.savetxtint 格式,像这样-

    In [69]: np.savetxt("output.txt", np.argwhere(x>0.3), fmt="%d", comments='')
    
    In [70]: !cat output.txt
    0 1
    0 2
    1 0
    1 2
    2 0
    2 1
    2 2
    

    使用基于1 的索引,将1 添加到np.argwhere 输出 -

    In [71]: np.savetxt("output.txt", np.argwhere(x>0.3)+1, fmt="%d", comments='')
    
    In [72]: !cat output.txt
    1 2
    1 3
    2 1
    2 3
    3 1
    3 2
    3 3
    

    【讨论】:

    • 感谢您的回答。但是,当我使用 zip(r,c) 时,它会在内存中创建一个 zip 对象。如何将它们打印到文件中?
    • @podedo 我猜如果你使用的是 Python 3.x,你需要list(zip(r,c))。关于打印到文件,我不确定。
    • @podedo 添加了关于写入文本文件的部分。看看吧!
    【解决方案2】:

    您可以使用 np.where,它返回两个数组(当应用于二维数组时),其中行(和相应列)的索引满足您指定为参数的条件。 然后你可以压缩这两个数组来取回一个元组列表:

    list(zip(*np.where(x > 0.3)))
    

    如果你想给每个元组的每个元素加 1(使用基于 1 的索引),要么循环遍历元组,要么给 where:返回的每个数组加 1:

    res = np.where(x > 0.3)
    res[0] += 1  # adds one to every element of res[0] thanks to broadcasting
    res[1] += 1
    list(zip(*res))
    

    【讨论】:

    • 很干净!谢谢你。但是如何为每个元组添加 +1 呢?
    猜你喜欢
    • 2023-03-29
    • 2018-05-07
    • 2019-11-01
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2011-03-06
    相关资源
    最近更新 更多