如何从结构化的numpy数组中删除列?

Dob*_*ead 13 python numpy

我有另一个基本问题,我无法找到答案,但似乎应该很容易做到.

好吧,假设你有一个结构化的numpy数组,它是从csv生成的,第一行是字段名.该数组具有以下形式:

dtype([('A', '<f8'), ('B', '<f8'), ('C', '<f8'), ..., ('n','<f8'])
Run Code Online (Sandbox Code Playgroud)

现在,假设您要从此数组中删除"ith"列.有没有方便的方法呢?

我希望它像删除一样工作:

new_array = np.delete(old_array, 'i')
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

War*_*ser 17

它不是一个单独的函数调用,但以下显示了一种删除第i个字段的方法:

In [67]: a
Out[67]: 
array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)], 
      dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<f8')])

In [68]: i = 1   # Drop the 'B' field

In [69]: names = list(a.dtype.names)

In [70]: names
Out[70]: ['A', 'B', 'C']

In [71]: new_names = names[:i] + names[i+1:]

In [72]: new_names
Out[72]: ['A', 'C']

In [73]: b = a[new_names]

In [74]: b
Out[74]: 
array([(1.0, 3.0), (4.0, 6.0)], 
      dtype=[('A', '<f8'), ('C', '<f8')])
Run Code Online (Sandbox Code Playgroud)

作为一个功能包装:

def remove_field_num(a, i):
    names = list(a.dtype.names)
    new_names = names[:i] + names[i+1:]
    b = a[new_names]
    return b
Run Code Online (Sandbox Code Playgroud)

删除给定的字段名称可能更自然:

def remove_field_name(a, name):
    names = list(a.dtype.names)
    if name in names:
        names.remove(name)
    b = a[names]
    return b
Run Code Online (Sandbox Code Playgroud)

另外,查看matplotlib 模块的一部分drop_rec_fields功能.mlab


更新:请参阅我的答案如何从结构化的numpy数组中删除列*而不复制它*?用于创建结构化数组的字段的子集视图而不制作数组副本的方法.


jez*_*jez 6

通过Google搜索并从Warren的回答中了解了我需要了解的内容,我无法拒绝发布更简洁的版本,添加选项可以一次性有效地删除多个字段:

def rmfield( a, *fieldnames_to_remove ):
    return a[ [ name for name in a.dtype.names if name not in fieldnames_to_remove ] ]
Run Code Online (Sandbox Code Playgroud)

例子:

a = rmfield(a, 'foo')
a = rmfield(a, 'foo', 'bar')  # remove multiple fields at once
Run Code Online (Sandbox Code Playgroud)

或者,如果我们真的打高尔夫球,以下是相同的:

rmfield=lambda a,*f:a[[n for n in a.dtype.names if n not in f]]
Run Code Online (Sandbox Code Playgroud)

  • 也许您没有读过“如果我们真的要去打高尔夫球”这句话。...“代码打高尔夫球”的目的是创建最短的代码,而不论其可读性如何,而且几乎永远不会丑陋。 (2认同)