[英]Delete column from a numpy structured array (list of tuples in the array)?
我使用外部庫函數返回一個numpy結構化數組。
cities_array
>>> array([ (1, [-122.46818353792992, 48.74387985436505], u'05280', u'Bellingham', u'53', u'Washington', u'5305280', u'city', u'N', -99, 52179),
(2, [-109.67985528815007, 48.54381826401885], u'35050', u'Havre', u'30', u'Montana', u'3035050', u'city', u'N', 2494, 10201),
(3, [-122.63068540357023, 48.49221584868184], u'01990', u'Anacortes', u'53', u'Washington', u'5301990', u'city', u'N', -99, 11451),
...,
(3147, [-156.45657614262274, 20.870633142444376], u'22700', u'Kahului', u'15', u'Hawaii', u'1522700', u'census designated place', u'N', 7, 16889),
(3148, [-156.45038252004554, 20.76059218396], u'36500', u'Kihei', u'15', u'Hawaii', u'1536500', u'census designated place', u'N', -99, 11107),
(3149, [-155.08472452266503, 19.693112205773275], u'14650', u'Hilo', u'15', u'Hawaii', u'1514650', u'census designated place', u'N', 38, 37808)],
dtype=[('ID', '<i4'), ('Shape', '<f8', (2,)), ('CITY_FIPS', '<U5'), ('CITY_NAME', '<U40'), ('STATE_FIPS', '<U2'), ('STATE_NAME', '<U25'), ('STATE_CITY', '<U7'), ('TYPE', '<U25'), ('CAPITAL', '<U1'), ('ELEVATION', '<i4'), ('POP1990', '<i4')])
cities_array
的類型為<type 'numpy.ndarray'>
。
我可以訪問數組的各個列:
cities_array[['ID','CITY_NAME']]
>>> array([(1, u'Bellingham'), (2, u'Havre'), (3, u'Anacortes'), ...,
(3147, u'Kahului'), (3148, u'Kihei'), (3149, u'Hilo')],
dtype=[('ID', '<i4'), ('CITY_NAME', '<U40')])
現在我要刪除第一列ID
。 幫助和SO問題說它應該是numpy.delete
。
運行時: numpy.delete(cities_array,cities_array['ID'],1)
我收到錯誤信息:
...in delete
N = arr.shape[axis]
IndexError: tuple index out of range
我究竟做錯了什么? 我應該對cities_array進行后期處理才能使用數組嗎?
我在Python 2.7.10和numpy 1.11.0上
我認為這應該有效:
def delete_colum(array, *args):
filtered = [x for x in array.dtype.names if x not in args]
return array[filtered]
數組示例:
a
Out[9]:
array([(1, [-122.46818353792992, 48.74387985436505])],
dtype=[('ID', '<i4'), ('Shape', '<f8', (2,))])
delete_colum(a,'ID')
Out[11]:
array([([-122.46818353792992, 48.74387985436505],)],
dtype=[('Shape', '<f8', (2,))])
你評論:
但是這樣的基本操作失敗並不奇怪嗎? 只是一個簡單的數組
x = numpy.zeros(3, dtype={'names':['col1', 'col2'], 'formats':['i4','f4']})
無法刪除一列numpy.delete(x,0,1)
。 什么是這個問題的潰敗原因,任何想法?
np.delete
不是基本操作。 看看它的代碼。 它長5屏(在Ipython上)。 其中許多處理指定刪除元素的不同方式。
對於np.delete(x,0,axis = 1)
它使用了一個特例
# optimization for a single value
...
newshape[axis] -= 1
new = empty(newshape, arr.dtype, arrorder)
slobj[axis] = slice(None, obj)
new[slobj] = arr[slobj]
slobj[axis] = slice(obj, None)
slobj2 = [slice(None)]*ndim
slobj2[axis] = slice(obj+1, None)
new[slobj] = arr[slobj2]
對於2d數組,軸= 1,它確實:
new = np.zeros((x.shape[0], x.shape[1]-1), dtype=x.dtype)
new[:, :obj] = x[:, :obj]
new[:, obj:] = x[:, obj+1:]
換句話說,它分配一個新的數組,列少一列,然后從原始數據復制兩個切片到它。
有多個刪除列和布爾obj
它需要其他路由。
請注意,該操作的基礎是能夠索引2個維度。
但你不能用這種方式索引你的x
。 x[0,1]
給出了too many indices
錯誤。 你必須使用x[0]['col1']
。 索引dtype
的字段與索引2d數組的列根本不同。
該recfunctions
操縱dtype
的方式,定期領域numpy
功能沒有。 基於之前的研究,我猜測drop_field
的確是這樣的:
In [57]: x # your x with some values
Out[57]:
array([(1, 3.0), (2, 2.0), (3, 1.0)],
dtype=[('col1', '<i4'), ('col2', '<f4')])
目標數組,具有不同的dtype
(缺少一個字段)
In [58]: y=np.zeros(x.shape, dtype=x.dtype.descr[1:])
按字段復制值:
In [60]: for name in y.dtype.names:
...: y[name]=x[name]
In [61]: y
Out[61]:
array([(3.0,), (2.0,), (1.0,)],
dtype=[('col2', '<f4')])
常規nd索引是圍繞shape
和strides
屬性構建的。 利用這些(和元素字節大小),它可以快速識別所需元素的data
緩沖區中的位置。
使用復合dtype
,形狀和步幅以相同的方式工作,但是nbytes
是不同的。 在你的x
情況下, i4
和f4
字段各為24 - 12。 因此,從一個24位記錄到下一個記錄的常規索引步驟。 因此,要選擇“col2”字段,需要在每個記錄中選擇第二組4個字節。
在可能的情況下,我認為它將字段選擇轉換為常規索引。 __array_interface__
是一個很好的數組基本屬性字典。
In [70]: x.__array_interface__
Out[70]:
{'data': (68826112, False),
'descr': [('col1', '<i4'), ('col2', '<f4')],
'shape': (3,),
'strides': None,
'typestr': '|V8',
'version': 3}
In [71]: x['col2'].__array_interface__
Out[71]:
{'data': (68826116, False),
'descr': [('', '<f4')],
'shape': (3,),
'strides': (8,),
'typestr': '<f4',
'version': 3}
第二個數組指向相同的數據緩沖區,但進一步指向4個字節(第一個col2
值)。 實際上它是一種觀點。
( np.transpose
是不跨越操作另一個函數dtype
邊界。)
===================
這是drop_fields
的代碼(匯總):
In [74]: from numpy.lib import recfunctions # separate import statement
In [75]: recfunctions.drop_fields??
def drop_fields(base, drop_names, usemask=True, asrecarray=False):
.... # define `drop_descr function
newdtype = _drop_descr(base.dtype, drop_names)
output = np.empty(base.shape, dtype=newdtype)
output = recursive_fill_fields(base, output)
return output
recursive_fill_fields
按名稱字段副本執行名稱,並且能夠處理定義字段內的字段的dtypes(遞歸部分)。
In [81]: recfunctions.drop_fields(x, 'col1')
Out[81]:
array([(3.0,), (2.0,), (1.0,)],
dtype=[('col2', '<f4')])
In [82]: x[['col2']] # multifield selection that David suggests
Out[82]:
array([(3.0,), (2.0,), (1.0,)],
dtype=[('col2', '<f4')])
In [83]: x['col2'] # single field view
Out[83]: array([ 3., 2., 1.], dtype=float32)
drop_field
產生與@David建議的多字段索引類似的結果。 但是,多字段索引編寫得很糟糕,因為您將看到是否嘗試某種分配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.