【问题标题】:Delete column from a numpy structured array (list of tuples in the array)?从 numpy 结构化数组(数组中的元组列表)中删除列?
【发布时间】:2016-04-25 10:02:13
【问题描述】:

我使用了一个外部库函数,它返回一个 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 的类型为 &lt;type 'numpy.ndarray'&gt;

我可以访问数组的各个列:

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')])

现在我想删除第一列IDhelpSO questions 说它应该是 numpy.delete

运行时:numpy.delete(cities_array,cities_array['ID'],1) 我收到错误消息:

...in delete
    N = arr.shape[axis]
IndexError: tuple index out of range

我做错了什么?我应该对 city_array 进行后处理以便能够使用该数组吗?

我使用的是 Python 2.7.10 和 numpy 1.11.0

【问题讨论】:

  • 如答案所示,您可以查看数据类型名称的子集。这不是真正的删除。还有一个可能实现删除副本的 recfuncs 库。
  • numpy.lib.recfunctions.drop_fields
  • @hpaulj,感谢您的评论,很高兴知道有一个外部库。但是这样一个基本的操作失败了不是很奇怪吗?只是一个简单的数组x = numpy.zeros(3, dtype={'names':['col1', 'col2'], 'formats':['i4','f4']}) 无法删除带有numpy.delete(x,0,1) 的列。这个问题的溃败原因是什么,有什么想法吗?

标签: python arrays python-2.7 numpy


【解决方案1】:

我认为这应该可行:

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,))])

【讨论】:

    【解决方案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]
    

    对于二维数组,axis=1 是这样:

    new = np.zeros((x.shape[0], x.shape[1]-1), dtype=x.dtype)
    new[:, :obj] = x[:, :obj]
    new[:, obj:] = x[:, obj+1:]
    

    换句话说,它分配一个少1列的新数组,然后将两个切片从原始数组复制到它。

    使用多个删除列和布尔值obj 它采用其他路线。

    请注意,该操作的基础是索引二维的能力。

    但是你不能这样索引你的xx[0,1] 给出 too many indices 错误。你必须使用x[0]['col1']。索引dtype 的字段与索引二维数组的列根本不同。

    recfunctions 以常规 numpy 函数所不具备的方式操纵 dtype 字段。根据之前的研究,我猜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')])
    

    常规的 n-d 索引是围绕 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 通过名称字段复制名称,并且能够处理在字段中定义字段的数据类型(递归部分)。

    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 建议的多字段索引类似的结果。但是,多字段索引的开发很差,如果您尝试某种分配,您会看到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2015-03-01
      • 2015-09-14
      相关资源
      最近更新 更多