如何从结构化numpy数组中删除列?
我还有一个基本问题,我一直无法找到答案,但看起来应该很容易做到。如何从结构化numpy数组中删除列?
好吧,想象你有一个结构化的numpy数组,从csv生成,第一行为字段名称。该阵列的形式:
dtype([('A', '<f8'), ('B', '<f8'), ('C', '<f8'), ..., ('n','<f8'])
现在,让我们说你想从这个数组中删除'ith'列。有没有一种方便的方法来做到这一点?
我想要它像删除工作:
new_array = np.delete(old_array, 'i')
任何想法?
这不是很一个函数调用,但下面显示下降的第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*?用于创建一个结构数组的字段的子集的视图,而不该数组的副本的方法。
+1 3分钟之内击败我! – Jaime 2013-03-22 18:42:08
@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]]
如果我可以这样说,你的第二个解决方案是相当难看的。特别是我不喜欢使用lambda表达式来实现函数声明。这不是一个好的风格,很难阅读。其他人似乎同意我的观点:http://*.com/a/134638/1375015 – 2016-05-06 18:12:55
也许你没有阅读过“如果我们真的打算打高尔夫球”这句话......“code golf “是创建最短的代码,而不考虑可读性,并且几乎永远不会变得丑陋。 – jez 2016-05-06 18:48:27
我不知道那句话。我仍然没有看到这一点,但在这种情况下,我的回应可能有点苛刻。 – 2016-05-06 18:57:10
都是dtypes f8吗? – 2013-03-22 18:41:39