#python #numpy #multidimensional-array
#python #numpy #многомерный массив
Вопрос:
У меня есть следующий цикл
# `results` are obtained from some mySQldb command.
for row in results:
print row
Который печатает кортежи следующим образом:
('1A34', 'RBP', 0.0, 1.0, 0.0, 0.0, 0.0, 0.0)
('1A9N', 'RBP', 0.0456267, 0.0539268, 0.331932, 0.0464031, 4.41336e-06, 0.522107)
('1AQ3', 'RBP', 0.0444479, 0.201112, 0.268581, 0.0049757, 1.28505e-12, 0.480883)
('1AQ4', 'RBP', 0.0177232, 0.363746, 0.308995, 0.00169861, 0.0, 0.307837)
Мой вопрос из этой итерации, как я могу создать неровный nd.array, который выглядит следующим образом:
array([['1A34', 'RBP', 0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
['1A9N', 'RBP', 0.0456267, 0.0539268, 0.331932, 0.0464031, 4.41336e-06, 0.522107],
['1AQ3', 'RBP', 0.0444479, 0.201112, 0.268581, 0.0049757, 1.28505e-12, 0.480883],
['1AQ4', 'RBP', 0.0177232, 0.363746, 0.308995, 0.00169861, 0.0, 0.307837]])
В конце ndarray будет иметь форму: (4,8)
Комментарии:
1. Вам нужно иметь
str
иfloat
в одномarray
? Это можно сделать,structured array
но это не идеальное решение. Обычный массив допускает только один тип (dtype
как известно). Рассматриваете возможность использованияpandas
?2. Если
results
это генератор, вам нужно сначала преобразовать его в список. Причина в том, что массивы numpy должны знать их размер во время создания. Если вы знаете количество элементов вresults
, то вы можете сделать что-то вродеa = numpy.empty((n, 8), dtype='object')
, за которым следует:for i, row in enumerate(results): a[i] = row
.3. @AlokSinghal, не совсем верно, есть
numpy.fromiter
функция.4. @CTZhu спасибо, что упомянули об этом. Хотя кажется
fromiter
, что перераспределяет массив для каждого нового элемента, еслиcount
не указано иное. Редактировать : просто посмотрел на исходный код, и, похоже, он увеличивается на 50% при каждом новом распределении, так что это может быть не так плохо, как я думал.
Ответ №1:
Считайте его в структурированный массив:
In [30]:
a=[('1A34', 'RBP', 0.0, 1.0, 0.0, 0.0, 0.0, 0.0),
('1A9N', 'RBP', 0.0456267, 0.0539268, 0.331932, 0.0464031, 4.41336e-06, 0.522107),
('1AQ3', 'RBP', 0.0444479, 0.201112, 0.268581, 0.0049757, 1.28505e-12, 0.480883),
('1AQ4', 'RBP', 0.0177232, 0.363746, 0.308995, 0.00169861, 0.0, 0.307837)]
np.array(a, dtype=('a10,a10,f4,f4,f4,f4,f4,f4'))
Out[30]:
array([('1A34', 'RBP', 0.0, 1.0, 0.0, 0.0, 0.0, 0.0),
('1A9N', 'RBP', 0.045626699924468994, 0.053926799446344376, 0.331932008266449, 0.04640309885144234, 4.413359874888556e-06, 0.5221070051193237),
('1AQ3', 'RBP', 0.044447898864746094, 0.20111200213432312, 0.26858100295066833, 0.004975699819624424, 1.2850499744171406e-12, 0.48088300228118896),
('1AQ4', 'RBP', 0.01772320084273815, 0.3637459874153137, 0.30899500846862793, 0.0016986100235953927, 0.0, 0.30783700942993164)],
dtype=[('f0', 'S10'), ('f1', 'S10'), ('f2', '<f4'), ('f3', '<f4'), ('f4', '<f4'), ('f5', '<f4'), ('f6', '<f4'), ('f7', '<f4')])
Вы можете иметь их все в object
dtype
:
In [46]:
np.array(a, dtype=object)
Out[46]:
array([['1A34', 'RBP', 0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
['1A9N', 'RBP', 0.0456267, 0.0539268, 0.331932, 0.0464031,
4.41336e-06, 0.522107],
['1AQ3', 'RBP', 0.0444479, 0.201112, 0.268581, 0.0049757,
1.28505e-12, 0.480883],
['1AQ4', 'RBP', 0.0177232, 0.363746, 0.308995, 0.00169861, 0.0,
0.307837]], dtype=object)
но это не идеально для float
значений, также это может привести к нежелательному поведению:
In [48]:
b=np.array(a, dtype=object)
b[0] b[1] #addition for float values and concatenation for string values
Out[48]:
array(['1A341A9N', 'RBPRBP', 0.0456267, 1.0539268, 0.331932, 0.0464031,
4.41336e-06, 0.522107], dtype=object)
pandas
также является альтернативой:
In [43]:
import pandas as pd
print pd.DataFrame(a)
0 1 2 3 4 5 6 7
0 1A34 RBP 0.000000 1.000000 0.000000 0.000000 0.000000e 00 0.000000
1 1A9N RBP 0.045627 0.053927 0.331932 0.046403 4.413360e-06 0.522107
2 1AQ3 RBP 0.044448 0.201112 0.268581 0.004976 1.285050e-12 0.480883
3 1AQ4 RBP 0.017723 0.363746 0.308995 0.001699 0.000000e 00 0.307837
In [44]:
pd.DataFrame(a).dtypes
Out[44]:
0 object
1 object
2 float64
3 float64
4 float64
5 float64
6 float64
7 float64
dtype: object
и это позволяет столбцам иметь разные dtype
Комментарии:
1. Спасибо за предложение panda. Но мне нужен numpy, как того требует scikit-learn.
2.Добро пожаловать, в этом случае я буду рекомендовать кодировать строковые значения для фиктивных переменных или факторов (0, 1, 2, 3… ), таким образом, каждая вещь может быть помещена в обычную
numpy
array
float
dtype
3. это
undesired behaviour
исключительно дляobject
типа данных? Если я жестко закодирую, используя ваше предложениеdtype=[('f0', 'S10'), ('f1', 'S10'), ('f2', '<f4'), ('f3', '<f4'), ('f4', '<f4'), ('f5', '<f4'), ('f6', '<f4'), ('f7', '<f4')])
, этот побочный эффект не должен возникать, верно?4. Кстати, форма
(4,)
не(4,8)
является . Как я могу сделать это правильно, чтобы получить последнюю форму?5. Да, как только у вас есть данные в a
structured array
, форма становится(4,)
.8
исчез (и вместо этого у вас теперь есть8
поля,f0
tof7
).