簡體   English   中英

從numpy結構化數組中刪除列(數組中的元組列表)?

[英]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索引是圍繞shapestrides屬性構建的。 利用這些(和元素字節大小),它可以快速識別所需元素的data緩沖區中的位置。

使用復合dtype ,形狀和步幅以相同的方式工作,但是nbytes是不同的。 在你的x情況下, i4f4字段各為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM