假设你有一个结构化的NumPy数组,从CSV文件中生成,其中第一行是字段名。数组的形式如下:
dtype([('A', '<f8'), ('B', '<f8'), ('C', '<f8'), ..., ('n','<f8'])
现在,假设你想从这个数组中移除第'i'列。有没有方便的方法可以这样做?
我希望它能像删除一样工作:
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
另外,请查看属于matplotlib的mlab
模块中的drop_rec_fields
函数。
通过谷歌搜索并从Warren的回答中了解了我需要知道的内容后,我忍不住发布了一个更加简洁的版本,并添加了一次性高效地删除多个字段的选项:
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]]
import numpy.lib.recfunctions as recfc
points_array = recfc.drop_fields(points_array, "classes", usemask=False)