【问题标题】:Finding matching subset of "row" in a numpy structured array在 numpy 结构化数组中查找“行”的匹配子集
【发布时间】:2021-08-21 00:05:36
【问题描述】:

我将数据存储在 NumPy 结构化数组中,其中部分信息标识了各种情况。我想找到与给定案例匹配的 row。例如,假设我将建筑物的名称、房间号以及房间中的椅子和桌子的数量存储在 (2,) 数组中。然后看起来像这样:

import numpy as np

my_dtype = [('building', '<U5'), ('room', '<i8'), ('seating', '<i8', (2,))]
room_info = np.array([('BLDG0', 12, [24, 6]),
                      ('BLDG1', 34, [32, 10]),
                      ('BLDG0', 14, [10, 20])],
                      dtype=my_dtype)

现在说我想找到建筑物'BLDG0',房间14的行。根据Finding a matching row in a numpy matrix的回答,我试过了

sub_fields = ['building', 'room']
matching_index, = np.where(room_info[sub_fields] == ('BLDG0', 14))

理想情况下会产生[2]。但是,这会导致以下警告:

FutureWarning: elementwise == comparison failed and returning scalar instead; this will raise an error or perform elementwise comparison in the future.

并返回一个空数组。除了分别比较每个然后找到匹配的索引之外,有没有办法为大量数据找到匹配的子

我正在通过 miniconda 使用 NumPy 版本 1.18.5,看起来我无法在此环境中安全地更新到更新版本。 (虽然我不确定新版本是否支持这种类型的比较)

【问题讨论】:

    标签: python numpy structured-array


    【解决方案1】:
    In [243]: my_dtype = [('building', '<U5'), ('room', '<i8'), ('seating', '<i8', (
         ...: 2,))]
         ...: room_info = np.array([('BLDG0', 12, [24, 6]),
         ...:                       ('BLDG1', 34, [32, 10]),
         ...:                       ('BLDG0', 14, [10, 20])],
         ...:                       dtype=my_dtype)
    In [244]: room_info
    Out[244]: 
    array([('BLDG0', 12, [24,  6]), ('BLDG1', 34, [32, 10]),
           ('BLDG0', 14, [10, 20])],
          dtype=[('building', '<U5'), ('room', '<i8'), ('seating', '<i8', (2,))])
    
    In [246]: room_info['building']
    Out[246]: array(['BLDG0', 'BLDG1', 'BLDG0'], dtype='<U5')
    In [247]: room_info['building']=='BLDG0'
    Out[247]: array([ True, False,  True])
    
    In [248]: room_info['room']==14
    Out[248]: array([False, False,  True])
    

    将两者结合起来:

    In [249]: Out[247] & Out[248]
    Out[249]: array([False, False,  True])
    

    将其用作布尔掩码:

    In [250]: room_info[_]
    Out[250]: 
    array([('BLDG0', 14, [10, 20])],
          dtype=[('building', '<U5'), ('room', '<i8'), ('seating', '<i8', (2,))])
    

    并获取索引:

    In [251]: np.nonzero(Out[247]&Out[248])
    Out[251]: (array([2]),)
    

    看起来我们可以使用正确构造的结构化数组来测试这两个字段:

    In [254]: test=np.array(('BLDG0',14),dtype=my_dtype[:2])
    In [255]: room_info[['building','room']]
    Out[255]: 
    array([('BLDG0', 12), ('BLDG1', 34), ('BLDG0', 14)],
          dtype={'names':['building','room'], 'formats':['<U5','<i8'], 'offsets':[0,20], 'itemsize':44})
    In [256]: room_info[['building','room']]==test
    Out[256]: array([False, False,  True])
    

    【讨论】:

    • 谢谢!最后一部分是我一直在寻找的。我没有意识到我必须使用 case 创建另一个结构化数组才能进行我想要的行比较。
    • 一个普通的元组或元组列表将被转换为一个“默认”数组,(2 元素字符串 dtype),这是行不通的。结构化数组需要额外的注意以确保 dtypes 是正确的。
    猜你喜欢
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多