【问题标题】:Create a new array from numpy array based on the conditions from a list根据列表中的条件从 numpy 数组创建一个新数组
【发布时间】:2011-04-06 03:21:53
【问题描述】:

假设我有一个由以下定义的数组:

data = np.array([('a1v1', 'a2v1', 'a3v1', 'a4v1', 'a5v1'),
       ('a1v1', 'a2v1', 'a3v1', 'a4v2', 'a5v1'),
       ('a1v3', 'a2v1', 'a3v1', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v2', 'a3v1', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v3', 'a3v2', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v3', 'a3v2', 'a4v2', 'a5v1'),
       ('a1v3', 'a2v3', 'a3v2', 'a4v2', 'a5v2'),
       ('a1v1', 'a2v2', 'a3v1', 'a4v1', 'a5v1'),
       ('a1v1', 'a2v3', 'a3v2', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v2', 'a3v2', 'a4v1', 'a5v2'),
       ('a1v1', 'a2v2', 'a3v2', 'a4v2', 'a5v2'),
       ('a1v3', 'a2v2', 'a3v1', 'a4v2', 'a5v2'),
       ('a1v3', 'a2v1', 'a3v2', 'a4v1', 'a5v2'),
       ('a1v2', 'a2v2', 'a3v1', 'a4v2', 'a5v1')],
      dtype=[('a1', '|S4'), ('a2', '|S4'), ('a3', '|S4'),
             ('a4', '|S4'), ('a5', '|S4')])

如何创建一个函数来按行列出数据元素,条件是在元组列表 r 中给出的条件。

r = [('a1', 'a1v1'), ('a4', 'a4v1')]

我知道可以这样手动完成:

data[(data['a1']=='a1v1') & data['a4']=='a4v1']

如何从符合 r 的数据中删除行。

data[(data['a1']!='a1v1') | data['a4']!='a4v1']

谢谢。

【问题讨论】:

    标签: python arrays numpy recarray


    【解决方案1】:

    如果我的理解正确,您想列出整行,其中给定的列元组等于某个值。在这种情况下,这应该是您想要的,尽管它有点冗长和晦涩:

    test_cols = data[['a1', 'a4']]
    test_vals = np.array(('a1v1', 'a4v1'), test_cols.dtype)
    data[test_cols == test_vals]
    

    注意“嵌套列表”样式索引...这是选择结构化数组的多个列的最简单方法。例如。

    data[['a1', 'a4']] 
    

    将产生

    array([('a1v1', 'a4v1'), ('a1v1', 'a4v2'), ('a1v3', 'a4v1'),
           ('a1v2', 'a4v1'), ('a1v2', 'a4v1'), ('a1v2', 'a4v2'),
           ('a1v3', 'a4v2'), ('a1v1', 'a4v1'), ('a1v1', 'a4v1'),
           ('a1v2', 'a4v1'), ('a1v1', 'a4v2'), ('a1v3', 'a4v2'),
           ('a1v3', 'a4v1'), ('a1v2', 'a4v2')], 
          dtype=[('a1', '|S4'), ('a4', '|S4')])
    

    然后,您可以对您正在检查的值的元组进行测试,并获得一个一维布尔数组,其中这些列等于这些值。

    但是,对于结构化数组,dtype 必须完全匹配。例如。 data[['a1', 'a4']] == ('a1v1', 'a4v1') 只是产生False,所以我们必须使用与我们正在测试的列相同的 dtype 来创建一个我们想要测试的值的数组。因此,我们必须这样做:

    test_cols = data[['a1', 'a4']]
    test_vals = np.array(('a1v1', 'a4v1'), test_cols.dtype)
    

    在我们这样做之前:

    data[test_cols == test_vals]
    

    这产生了我们最初追求的东西:

    array([('a1v1', 'a2v1', 'a3v1', 'a4v1', 'a5v1'),
           ('a1v1', 'a2v2', 'a3v1', 'a4v1', 'a5v1'),
           ('a1v1', 'a2v3', 'a3v2', 'a4v1', 'a5v2')], 
          dtype=[('a1', '|S4'), ('a2', '|S4'), ('a3', '|S4'), ('a4', '|S4'), ('a5', '|S4')])
    

    希望这是有道理的,无论如何......

    【讨论】:

    • 如果 r 不是按数据 dtype 的顺序怎么办?例如,r = [('a4', 'a4v1'), ('a1', 'a1v1')]。
    • 是的,这是使用这种方法的一个问题。列必须以与 dtype 相同的顺序列出。 (或者,更确切地说,它们将按 dtype 的顺序返回,无论它们列出的顺序如何。)我认为这只是结构化数组的设计限制......有一个补丁发布到邮件列表,(mail-archive.com/numpy-discussion@scipy.org/msg24453.html)但它显然从未进入 numpy 的主干版本......
    猜你喜欢
    • 2016-12-20
    • 2017-12-30
    • 2017-01-17
    • 2011-08-22
    • 2020-04-03
    • 1970-01-01
    • 2018-10-24
    • 2021-02-21
    • 1970-01-01
    相关资源
    最近更新 更多