2013-07-03 2 views
4

Я запускаю Numpy 1.6 в Python 2.7 и имею несколько 1D массивов, которые я получаю из другого модуля. Я хотел бы взять эти массивы и упаковать их в структурированный массив, чтобы я мог индексировать оригинальные массивы 1D по имени. У меня возникли проблемы с выяснением того, как получить 1D-массивы в 2D-массив и заставить dtype получить доступ к правильным данным. Мой MWE выглядит следующим образом:numpy Stacking 1D массивы в структурированный массив

>>> import numpy as np 
>>> 
>>> x = np.random.randint(10,size=3) 
>>> y = np.random.randint(10,size=3) 
>>> z = np.random.randint(10,size=3) 
>>> x 
array([9, 4, 7]) 
>>> y 
array([5, 8, 0]) 
>>> z 
array([2, 3, 6]) 
>>> 
>>> w = np.array([x,y,z]) 
>>> w.dtype=[('x','i4'),('y','i4'),('z','i4')] 
>>> w 
array([[(9, 4, 7)], 
     [(5, 8, 0)], 
     [(2, 3, 6)]], 
     dtype=[('x', '<i4'), ('y', '<i4'), ('z', '<i4')]) 
>>> w['x'] 
array([[9], 
     [5], 
     [2]]) 
>>> 
>>> u = np.vstack((x,y,z)) 
>>> u.dtype=[('x','i4'),('y','i4'),('z','i4')] 
>>> u 
array([[(9, 4, 7)], 
     [(5, 8, 0)], 
     [(2, 3, 6)]],  
     dtype=[('x', '<i4'), ('y', '<i4'), ('z', '<i4')]) 

>>> u['x'] 
array([[9], 
     [5], 
     [2]]) 

>>> v = np.column_stack((x,y,z)) 
>>> v 
array([[(9, 4, 7), (5, 8, 0), (2, 3, 6)]], 
     dtype=[('x', '<i4'), ('y', '<i4'), ('z', '<i4')]) 

>>> v.dtype=[('x','i4'),('y','i4'),('z','i4')] 
>>> v['x'] 
array([[9, 5, 2]]) 

Как вы можете видеть, в то время как мой оригинальный x массив содержит [9,4,7], никоим образом я пытался не складывать массивы, а затем индекс по 'x' возвращает оригинал x массива. Есть ли способ сделать это, или я не ошибаюсь?

+0

Нужно ли работать с массивом 2d? Почему бы просто не использовать словарь? – OregonTrail

+0

Я предполагаю, что я просто предположил, что было бы лучше не смешивать типы данных и использовать ndarray, поскольку он поддерживает индексирование с типом, но нет никаких реальных обоснований звука. – Thav

+0

Чтобы ответить на первый вопрос, нет, в этом случае мне не нужно работать с массивом 2d. – Thav

ответ

6

Один способ пойти

wtype=np.dtype([('x',x.dtype),('y',y.dtype),('z',z.dtype)]) 
w=np.empty(len(x),dtype=wtype) 
w['x']=x 
w['y']=y 
w['z']=z 

Обратите внимание, что размер каждого номера возвращаемый randint зависит от платформы, так что вместо int32, т.е. «i4», на моей машине у меня есть int64, который это «i8». Этот другой способ более переносимый.

+3

+1 Это на самом деле единственный способ получить массивы с разными типами данных в один структурированный массив. – Jaime

0

использовать словарь

#!/usr/bin/env python 

import numpy 

w = {} 
for key in ('x', 'y', 'z'): 
    w[key] = np.random.randint(10, size=3) 

print w 
3

Вы хотите использовать np.column_stack:

import numpy as np 

x = np.random.randint(10,size=3) 
y = np.random.randint(10,size=3) 
z = np.random.randint(10,size=3) 

w = np.column_stack((x, y, z)) 
w = w.ravel().view([('x', x.dtype), ('y', y.dtype), ('z', z.dtype)]) 

>>> w 
array([(5, 1, 8), (8, 4, 9), (4, 2, 6)], 
     dtype=[('x', '<i4'), ('y', '<i4'), ('z', '<i4')]) 
>>> x 
array([5, 8, 4]) 
>>> y 
array([1, 4, 2]) 
>>> z 
array([8, 9, 6]) 
>>> w['x'] 
array([5, 8, 4]) 
>>> w['y'] 
array([1, 4, 2]) 
>>> w['z'] 
array([8, 9, 6]) 
+0

Я использовал 'column_stack' в моем примере, но не получил те же результаты, что и вы. Я бы предположил, что разница в строке 'w.rave1() ...', но я не совсем понимаю, что там происходит. – Thav

+1

Это не удастся, если типы данных 1D-массивов занимают различное количество байтов. –

1

Вы можете посмотреть в рекордные массивы Numpy для такого использования:

«Numpy предоставляет мощные возможности для создавать массивы структур или записей. Эти массивы позволяют манипулировать данными с помощью структур или полей структуры. "

Вот документация на звукозаписывающих массивы: http://docs.scipy.org/doc/numpy/user/basics.rec.html

Вы можете использовать имена переменных в качестве имен полей.

Смежные вопросы