Преобразование массива 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 во время создания. Мне нужно высокопроизводительное и элегантное решение, которое будет хорошо работать для общих случаев, так как я буду делать этот тип преобразования много раз, для большого числа приложений.

Благодаря!

  • как вставить в таблицу mysql с помощью mysaldb, где имя таблицы находится в переменной python?
  • Вложенные f-строки
  • python optparse, как включить дополнительную информацию в использование?
  • CL-WHO-подобный HTML-шаблон для других языков?
  • Python, удаление всех файлов в папке старше X дней
  • Построение дерева решений с помощью pydot
  • Как использовать pyreverse в Windows
  • создать лямбда-функцию из строки ** правильно **
  • 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

    Тестирование классификации чувств Keras с помощью model.predict

    Как отлаживать возвышенные плагины во время разработки

    Удаление символов в печатной строке Python

    Render HTTP Response (HTML-контент) в selenium webdriver (браузер)

    Лучший способ сделать регистр без учета регистра, но соответствовать случаю слова, которое нужно заменить?

    Стоит ли использовать python re.compile?

    Как получить доступ к профилю пользователя в шаблоне Django?

    Пытается имитировать постоянный байт. Путаница с результатами time.sleep

    Ошибка при установке Python

    как получить электронную почту пользователя с помощью python social auth с помощью facebook и сохранить его

    Разберите JavaScript, возвращенный с BeautifulSoup

    Django Rest Framework {"detail": "Аутентификационные учетные данные не были предоставлены."}

    Установка pyodbc завершается с ошибкой на OSX 10.9 (Mavericks)

    Как проверить, является ли тип переменной строкой?

    Как получить сумму MD5 строки?

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