преобразование массива строковых полей в числовой формат - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть массив строк, сгруппированных в три поля:

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

Я хотел бы преобразовать в числовой массив (типа np.int8 для предпочтения, но не обязательно), в форме 4x3,вместо полей.

Мой общий подход - преобразовать массив 4x3 типа 'S2', а затем использовать astype, чтобы сделать его числовым.Единственная проблема заключается в том, что единственный подход, который я могу придумать, включает в себя как view, так и np.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 голосов
/ 26 января 2019

В последней версии numpy 1.16 добавлена ​​structured_to_unstructured, которая решает эту задачу:

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

В предыдущей версии numpy вы можете комбинировать x.data и np.frombuffer, чтобы создать другой массив из того жеданные в памяти без использования шагов.Это не приносит выигрыша в производительности, так как вычисления приводятся от приведения от S2 к int8.

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...