将字符串字段的numpy数组转换为数字格式

时间:2018-12-28 05:43:23

标签: python numpy

我有一个字符串数组,分为三个字段:

x = np.array([(-1, 0, 1),
              (-1, 1, 0),
              (0, 1, -1),
              (0, -1, 1)],
             dtype=[('a', 'S2'),
                    ('b', 'S2'),
                    ('c', 'S2')])

我想转换为4x3形状的数字数组(优先选择,类型为np.int8,而不是字段)。

我的一般方法是转换为类型为'S2'的4x3数组,然后使用astype将其设为数字​​。唯一的问题是,我能想到的唯一方法同时涉及viewnp.lib.stride_tricks.as_strided,这似乎不是一个非常可靠的解决方案:

y = np.lib.stride_tricks.as_strided(x.view(dtype='S2'),
                                    shape=(4, 3), strides=(6, 2))
z = y.astype(np.int8)

这适用于此处所示的玩具盒,但是我觉得必须有一种更简单的方法来解压缩所有具有相同dtype的字段的数组。有什么更健壮的选择?

1 个答案:

答案 0 :(得分:1)

添加了structured_to_unstructured的最新版本的numpy 1.16:

from numpy.lib.recfunctions import structured_to_unstructured
y = structured_to_unstructured(x)  # 2d array of 'S2'
z = y.astype(np.int8)

在先前版本的numpy中,您可以结合使用x.datanp.frombuffer从内存中的相同数据创建另一个数组,而不必使用跨步。不过,由于计算是由S2int8的转换驱动的,因此不会带来性能提升。

n = 1000

def f1(x):
    y = np.lib.stride_tricks.as_strided(x.view(dtype='S2'),
                                        shape=(n, 3),
                                        strides=(6, 2))
    return y.astype(np.int8)

def f2(x):
    y = np.frombuffer(x.data, dtype='S2').reshape((n, 3))
    return y.astype(np.int8)


x = np.array([(i%3-1, (i+1)%3-1, (i+2)%3-1)
              for i in xrange(n)],
             dtype='S2,S2,S2')

z1 = f1(x)
z2 = f2(x)
assert (z1==z2).all()