如何使用numpy将一维数组制作成二维数组?

时间:2014-11-20 01:54:17

标签: python arrays numpy

我的数据如下:

>>>npfilled[:5]

array([('!', 0, 0, 3, 10, 0, 2, 4, 4), ('!"', 0, 0, 0, 5, 0, 0, 0, 0),
       ('"', 23, 13, 20, 32, 0, 0, 22, 9),
       ("'", 21, 8, 23, 12, 5, 10, 0, 7), ('(', 3, 2, 2, 3, 0, 0, 0, 0)], 
      dtype=[('token', '<U64'), ('mel_freq1', '<i2'), ('mel_freq0', '<i2'), ('mel_freq2', '<i2'), ('mel_freq3', '<i2'), ('aus_freq0', '<i2'), ('aus_freq1', '<i2'), ('aus_freq2', '<i2'), ('aus_freq3', '<i2')])

>>>npfilled.shape
(301,)

但是我需要它(301,2),以便我可以对其进行切片并对其进行其他分析,这是我目前无法做到的。我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

在numpy术语中,您要问的是如何将结构化数组转换为“普通”2D数组,其中结构中的每个项目都沿着新轴。

简而言之,对于诸如此类的异构数据,pandas可能更适合您。

有人说过,这是一个快速的解释:


首先,要从当前结构化数组中对列进行切片,您可以执行以下操作:

import numpy as np

# Your example data...
data = np.array([('!', 0, 0, 3, 10, 0, 2, 4, 4),
                 ('!"', 0, 0, 0, 5, 0, 0, 0, 0),
                 ('"', 23, 13, 20, 32, 0, 0, 22, 9),
                 ("'", 21, 8, 23, 12, 5, 10, 0, 7),
                 ('(', 3, 2, 2, 3, 0, 0, 0, 0)],
        dtype=[('token', '<U64'), ('mel_freq1', '<i2'),
               ('mel_freq0', '<i2'), ('mel_freq2', '<i2'),
               ('mel_freq3', '<i2'), ('aus_freq0', '<i2'),
               ('aus_freq1', '<i2'), ('aus_freq2', '<i2'),
               ('aus_freq3', '<i2')])

# Print out two arbitrary columns.
print data[['token', 'aus_freq1']]

哪会给:

[(u'!', 2) (u'!"', 0) (u'"', 0) (u"'", 10) (u'(', 0)]

如果你有异构数据,你可能真的不想切换到“普通”数组。

但是,如果您确实想要将其切换,您可能会想到以下内容:

array([[u'!', 0, 0, 3, 10, 0, 2, 4, 4],
       [u'!"', 0, 0, 0, 5, 0, 0, 0, 0],
       [u'"', 23, 13, 20, 32, 0, 0, 22, 9],
       [u"'", 21, 8, 23, 12, 5, 10, 0, 7],
       [u'(', 3, 2, 2, 3, 0, 0, 0, 0]], dtype=object)

答案简短:


如果你不是非常关心内存使用情况,你可以这样做:

np.array(data.tolist(), dtype=object)

答案越长:

以上一行可以轻松获得你想要的东西。但是,这种方法有两个小缺点。

  1. 构建中间列表,
  2. 返回一个对象数组,其内存效率远低于原始结构化数组。
  3. 第二个问题无法解决。这就是结构化数组存在的原因。对象数组(指针数组)在内存中不像结构化数组那样紧凑,但它们可以容纳任意对象。

    但是,如果只想获得原始结构化数组的同类部分,那么你可以做类似的事情:

    # Only the first column is text...
    numeric_cols = list(data.dtype.names[1:])
    
    # View the non-text parts as an array with the same dtype as the numeric cols:
    data2d = data[numeric_cols].view('<i2')
    
    # And reshape it into a 2D array:
    data2d = data2d.reshape(-1, len(numeric_cols))
    

    这会产生:

    In [10]: data2d
    Out[10]: 
    array([[ 0,  0,  3, 10,  0,  2,  4,  4],
           [ 0,  0,  0,  5,  0,  0,  0,  0],
           [23, 13, 20, 32,  0,  0, 22,  9],
           [21,  8, 23, 12,  5, 10,  0,  7],
           [ 3,  2,  2,  3,  0,  0,  0,  0]], dtype=int16)
    

    这种方法比较冗长,但如果你有一个非常大的数组,它会更快。