Преобразование массива 2D numpy в структурированный массив

Я пытаюсь преобразовать двумерный массив в структурированный массив с именованными полями. Я хочу, чтобы каждая строка в 2D-массиве была новой записью в структурированном массиве. К сожалению, ничто из того, что я пробовал, работает так, как я ожидаю.

Я начинаю с:

>>> myarray = numpy.array([("Hello",2.5,3),("World",3.6,2)]) >>> print myarray [['Hello' '2.5' '3'] ['World' '3.6' '2']] 

Я хочу преобразовать в то, что выглядит так:

 >>> newarray = numpy.array([("Hello",2.5,3),("World",3.6,2)], dtype=[("Col1","S8"),("Col2","f8"),("Col3","i8")]) >>> print newarray [('Hello', 2.5, 3L) ('World', 3.6000000000000001, 2L)] 

Что я пробовал:

 >>> newarray = myarray.astype([("Col1","S8"),("Col2","f8"),("Col3","i8")]) >>> print newarray [[('Hello', 0.0, 0L) ('2.5', 0.0, 0L) ('3', 0.0, 0L)] [('World', 0.0, 0L) ('3.6', 0.0, 0L) ('2', 0.0, 0L)]] >>> newarray = numpy.array(myarray, dtype=[("Col1","S8"),("Col2","f8"),("Col3","i8")]) >>> print newarray [[('Hello', 0.0, 0L) ('2.5', 0.0, 0L) ('3', 0.0, 0L)] [('World', 0.0, 0L) ('3.6', 0.0, 0L) ('2', 0.0, 0L)]] 

Оба этих подхода пытаются преобразовать каждую запись в myarray в запись с данным dtype, поэтому добавляются дополнительные нули. Я не могу понять, как заставить его преобразовать каждую строку в запись.

Еще одна попытка:

 >>> newarray = myarray.copy() >>> newarray.dtype = [("Col1","S8"),("Col2","f8"),("Col3","i8")] >>> print newarray [[('Hello', 1.7219343871178711e-317, 51L)] [('World', 1.7543139673493688e-317, 50L)]] 

На этот раз фактическое преобразование не выполняется. Существующие данные в памяти просто повторно интерпретируются как новый тип данных.

Массив, с которого я начинаю, считывается из текстового файла. Типы данных не известны заранее, поэтому я не могу установить dtype во время создания. Мне нужно высокопроизводительное и элегантное решение, которое будет хорошо работать для общих случаев, так как я буду делать этот тип преобразования много раз, для большого числа приложений.

Благодаря!

4 Solutions collect form web for “Преобразование массива 2D numpy в структурированный массив”

Вы можете «создать массив записей из (плоского) списка массивов», используя numpy.core.records.fromarrays следующим образом:

 >>> import numpy as np >>> myarray = np.array([("Hello",2.5,3),("World",3.6,2)]) >>> print myarray [['Hello' '2.5' '3'] ['World' '3.6' '2']] >>> newrecarray = np.core.records.fromarrays(myarray.transpose(), names='col1, col2, col3', formats = 'S8, f8, i8') >>> print newrecarray [('Hello', 2.5, 3) ('World', 3.5999999046325684, 2)] 

Я пытался сделать что-то подобное. Я обнаружил, что когда numpy создал структурированный массив из существующего 2D-массива (используя np.core.records.fromarrays), он рассматривал каждый столбец (вместо каждой строки) в двухмерном массиве как запись. Поэтому вы должны перенести его. Такое поведение numpy не кажется очень интуитивным, но, возможно, для этого есть веская причина.

Я полагаю

 new_array = np.core.records.fromrecords([("Hello",2.5,3),("World",3.6,2)], names='Col1,Col2,Col3', formats='S8,f8,i8') 

это то, что вы хотите.

Хорошо, я боролся с этим какое-то время, но я нашел способ сделать это, что не требует больших усилий. Прошу прощения, если этот код «грязный» ….

Начнем с 2D-массива:

 mydata = numpy.array([['text1', 1, 'longertext1', 0.1111], ['text2', 2, 'longertext2', 0.2222], ['text3', 3, 'longertext3', 0.3333], ['text4', 4, 'longertext4', 0.4444], ['text5', 5, 'longertext5', 0.5555]]) 

Таким образом, мы получаем 2D-массив с 4 столбцами и 5 строками:

 mydata.shape Out[30]: (5L, 4L) 

Чтобы использовать numpy.core.records.arrays – нам нужно указать входной аргумент как список массивов, поэтому:

 tuple(mydata) Out[31]: (array(['text1', '1', 'longertext1', '0.1111'], dtype='|S11'), array(['text2', '2', 'longertext2', '0.2222'], dtype='|S11'), array(['text3', '3', 'longertext3', '0.3333'], dtype='|S11'), array(['text4', '4', 'longertext4', '0.4444'], dtype='|S11'), array(['text5', '5', 'longertext5', '0.5555'], dtype='|S11')) 

Это создает отдельный массив для каждой строки данных. Но нам нужны входные массивы для столбца, поэтому нам понадобится:

 tuple(mydata.transpose()) Out[32]: (array(['text1', 'text2', 'text3', 'text4', 'text5'], dtype='|S11'), array(['1', '2', '3', '4', '5'], dtype='|S11'), array(['longertext1', 'longertext2', 'longertext3', 'longertext4', 'longertext5'], dtype='|S11'), array(['0.1111', '0.2222', '0.3333', '0.4444', '0.5555'], dtype='|S11')) 

Наконец, это должен быть список массивов, а не кортеж, поэтому мы завершаем приведенное выше в списке (), как показано ниже:

 list(tuple(mydata.transpose())) 

Это наш аргумент ввода данных отсортирован …. next – это dtype:

 mydtype = numpy.dtype([('My short text Column', 'S5'), ('My integer Column', numpy.int16), ('My long text Column', 'S11'), ('My float Column', numpy.float32)]) mydtype Out[37]: dtype([('My short text Column', '|S5'), ('My integer Column', '<i2'), ('My long text Column', '|S11'), ('My float Column', '<f4')]) 

Итак, теперь мы можем передать это на numpy.core.records.array ():

 myRecord = numpy.core.records.array(list(tuple(mydata.transpose())), dtype=mydtype) 

… и пальцы скрещены:

 myRecord Out[36]: rec.array([('text1', 1, 'longertext1', 0.11110000312328339), ('text2', 2, 'longertext2', 0.22220000624656677), ('text3', 3, 'longertext3', 0.33329999446868896), ('text4', 4, 'longertext4', 0.44440001249313354), ('text5', 5, 'longertext5', 0.5554999709129333)], dtype=[('My short text Column', '|S5'), ('My integer Column', '<i2'), ('My long text Column', '|S11'), ('My float Column', '<f4')]) 

Вуаля! Вы можете индексировать по имени столбца, как в:

 myRecord['My float Column'] Out[39]: array([ 0.1111 , 0.22220001, 0.33329999, 0.44440001, 0.55549997], dtype=float32) 

Надеюсь, это поможет, так как я потратил столько времени на использование numpy.asarray и mydata.astype и т. Д., Пытаясь заставить это работать, прежде чем, наконец, выработать этот метод.

Если данные начинаются как список кортежей, то создание структурированного массива выполняется прямо:

 In [228]: alist = [("Hello",2.5,3),("World",3.6,2)] In [229]: dt = [("Col1","S8"),("Col2","f8"),("Col3","i8")] In [230]: np.array(alist, dtype=dt) Out[230]: array([(b'Hello', 2.5, 3), (b'World', 3.6, 2)], dtype=[('Col1', 'S8'), ('Col2', '<f8'), ('Col3', '<i8')]) 

Усложнение состоит в том, что список кортежей был преобразован в массив строк 2d:

 In [231]: arr = np.array(alist) In [232]: arr Out[232]: array([['Hello', '2.5', '3'], ['World', '3.6', '2']], dtype='<U5') 

Мы могли бы использовать хорошо известный подход zip* для «переноса» этого массива – на самом деле мы хотим двойную транспозицию:

 In [234]: list(zip(*arr.T)) Out[234]: [('Hello', '2.5', '3'), ('World', '3.6', '2')] 

zip удобно предоставил нам список кортежей. Теперь мы можем воссоздать массив с желаемым dtype:

 In [235]: np.array(_, dtype=dt) Out[235]: array([(b'Hello', 2.5, 3), (b'World', 3.6, 2)], dtype=[('Col1', 'S8'), ('Col2', '<f8'), ('Col3', '<i8')]) 

В принятом ответе используются fromarrays :

 In [236]: np.rec.fromarrays(arr.T, dtype=dt) Out[236]: rec.array([(b'Hello', 2.5, 3), (b'World', 3.6, 2)], dtype=[('Col1', 'S8'), ('Col2', '<f8'), ('Col3', '<i8')]) 

Внутри, fromarrays использует общий подход к recfunctions : создайте целевой массив и скопируйте значения по имени поля. Эффективно это делает:

 In [237]: newarr = np.empty(arr.shape[0], dtype=dt) In [238]: for n, v in zip(newarr.dtype.names, arr.T): ...: newarr[n] = v ...: In [239]: newarr Out[239]: array([(b'Hello', 2.5, 3), (b'World', 3.6, 2)], dtype=[('Col1', 'S8'), ('Col2', '<f8'), ('Col3', '<i8')]) 
Interesting Posts

Как сохранить Excel-лист как HTML в Python?

IP-диапазон для преобразования CIDR в Python?

deadline = None после использования urlfetch.set_default_fetch_deadline (n)

Возьмем строку JSON, развязав ее в интерфейс на карте , редактируем и маршализируем ее в байт, кажется более сложным, тогда это должно быть

Очистка вложенных Try / Excepts

Как я могу получить список всех классов в текущем модуле в Python?

Почему тело запроса HTTP POST должно быть JSON, зарегистрированное в Python?

kmeans plot plot: график различных цветов для каждого кластера

Механизм Python для работы в Токио

Pandas эквивалент повторной выборки для целочисленного индекса

Заполнение Matplotlib между несколькими линиями

Наиболее эффективный способ удаления дубликатов из списка Python при сохранении порядка и удалении самого старого элемента

Реализация Python алгоритма упаковки

получить все ссылки HTML, используя lxml

Временное изменение значения переменной в Python

Python - лучший язык программирования в мире.