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

问题描述:

我还有一个基本问题,我一直无法找到答案,但看起来应该很容易做到。如何从结构化numpy数组中删除列?

好吧,想象你有一个结构化的numpy数组,从csv生成,第一行为字段名称。该阵列的形式:

dtype([('A', '<f8'), ('B', '<f8'), ('C', '<f8'), ..., ('n','<f8']) 

现在,让我们说你想从这个数组中删除'ith'列。有没有一种方便的方法来做到这一点?

我想要它像删除工作:

new_array = np.delete(old_array, 'i') 

任何想法?

+0

都是dtypes f8吗? – 2013-03-22 18:41:39

这不是很一个函数调用,但下面显示下降的第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')]) 

包裹起来作为一个函数:

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

这可能是更自然删除某一领域

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

此外,CH找出drop_rec_fields function,它是matplotlib的mlab module的一部分。


更新:见我的答案在How to remove a column from a structured numpy array *without copying it*?用于创建一个结构数组的字段的子集的视图,而不该数组的副本的方法。

+0

+1 3分钟之内击败我! – Jaime 2013-03-22 18:42:08

+1

@Jaime:勉强。 :)既然你删除了你的答案,我会提到删除字段名称而不是数字,这可能更自然。 – 2013-03-22 18:48:21

已经GOOGLE了这里的路上,得知我需要从沃伦的回答知道,我无法抗拒张贴了更为简洁的版本,添加的选项删除有效地一气呵成多个字段:

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

例子:

a = rmfield(a, 'foo') 
a = rmfield(a, 'foo', 'bar') # remove multiple fields at once 

或者,如果我们真的要高尔夫呢,下面是等价的:

rmfield=lambda a,*f:a[[n for n in a.dtype.names if n not in f]] 
+0

如果我可以这样说,你的第二个解决方案是相当难看的。特别是我不喜欢使用lambda表达式来实现函数声明。这不是一个好的风格,很难阅读。其他人似乎同意我的观点:http://*.com/a/134638/1375015 – 2016-05-06 18:12:55

+1

也许你没有阅读过“如果我们真的打算打高尔夫球”这句话......“code golf “是创建最短的代码,而不考虑可读性,并且几乎永远不会变得丑陋。 – jez 2016-05-06 18:48:27

+0

我不知道那句话。我仍然没有看到这一点,但在这种情况下,我的回应可能有点苛刻。 – 2016-05-06 18:57:10