numpy genfromtxt — вывод заголовка столбца, если заголовки не предоставлены

#python #numpy #genfromtxt

#python #numpy #genfromtxt

Вопрос:

Я понимаю, что с genfromtxt defaultfmt помощью параметра можно использовать для вывода имен столбцов по умолчанию, что полезно, если имена столбцов отсутствуют во входных данных. И defaultfmt , если не указано, по умолчанию f%i . Например.

 >>> data = StringIO("1 2 3n 4 5 6")
>>> np.genfromtxt(data, dtype=(int, float, int))
array([(1, 2.0, 3), (4, 5.0, 6)],
  dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<i8')])
  

Итак, здесь у нас есть автоматически созданные имена столбцов f0 , f1 , f2 .

Но что, если я хочу, чтобы numpy выводил как заголовки столбцов, так и тип данных? Я думал, что вы делаете это с dtype=None помощью . Вот так

 >>> data3 = StringIO("1 2 3n 4 5 6")
>>> np.genfromtxt(data3, dtype=None, ???)  # some parameter combo
array([(1, 2, 3), (4, 5, 6)],
  dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8')])  
  

Мне все еще нужны автоматически сгенерированные имена столбцов f0 , f1 … и т.д. И я хочу, чтобы numpy автоматически определял типы данных на основе данных, что, как я думал, было целым смыслом dtype=None .

РЕДАКТИРОВАТЬ, но, к сожалению, это не ВСЕГДА работает.

Этот случай работает, когда у меня есть как числа с плавающей запятой, так и целые числа.

 >>> data3b = StringIO("1 2 3.0n 4 5 6.0")
>>> np.genfromtxt(data3b, dtype=None)
array([(1, 2, 3.), (4, 5, 6.)],
  dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<f8')])
  

Таким образом, numpy правильно вывел тип данных i8 для первых 2 столбцов и f8 для последнего столбца.

Но, если я предоставлю все целые числа, выведенные имена столбцов исчезнут.

 >>> data3c = StringIO("1 2 3n 4 5 6")
>>> np.genfromtxt(data3c, dtype=None)
array([[1, 2, 3],
   [4, 5, 6]])
  

Мой идентичный код может работать или не работать в зависимости от входных данных? Это звучит неправильно.

И да, я знаю, что есть pandas. Но я не использую pandas специально. Поэтому, пожалуйста, отнеситесь ко мне с пониманием.

Комментарии:

1. Похоже, что все значения являются целыми числами, поэтому действие по умолчанию — возвращать обычный 2d-массив, а не структурированный массив.

2. Dtype не обязательно должен иметь имена. например. dtype='i,f,i' или ['i','f','i']

3. Спасибо. Вы говорите о передаче dtype? Дело в том, что я не хочу ничего передавать для dtype. Что касается всех целых чисел и сочетания целых чисел / чисел с плавающей точкой — похоже, что numpy делает то, что я хочу, если оно смешано, но не если все целые числа.

Ответ №1:

 In [2]: txt = '''1,2,3
   ...: 4,5,6'''.splitlines()
  

Defaylt 2d массив flaots:

 In [6]: np.genfromtxt(txt, delimiter=',',encoding=None)
Out[6]: 
array([[1., 2., 3.],
       [4., 5., 6.]])
  

2d целых чисел:

 In [7]: np.genfromtxt(txt, dtype=None, delimiter=',',encoding=None)
Out[7]: 
array([[1, 2, 3],
       [4, 5, 6]])
  

Указанные типы полей:

 In [8]: np.genfromtxt(txt, dtype='i,i,i', delimiter=',',encoding=None)
Out[8]: 
array([(1, 2, 3), (4, 5, 6)],
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
  

Указанные имена полей:

 In [9]: np.genfromtxt(txt, dtype=None, delimiter=',',encoding=None, names=['a','b','c'])
Out[9]: 
array([(1, 2, 3), (4, 5, 6)],
      dtype=[('a', '<i8'), ('b', '<i8'), ('c', '<i8')])
  

Неструктурированный массив может быть преобразован в структурированный с помощью:

 In [10]: import numpy.lib.recfunctions as rf
In [11]: rf.unstructured_to_structured(Out[7])
Out[11]: 
array([(1, 2, 3), (4, 5, 6)],
      dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8')])
  

По numpy умолчанию предпочтительный массив является многомерным числовым. Вот почему он выдает Out7] , если может.

Комментарии:

1. Спасибо. можете ли вы подробнее остановиться на последнем утверждении? Так numpy что по умолчанию используется неструктурированный, если это возможно? И, если я вас правильно понимаю, numpy считает, что неструктурированный — это нормально, если все int s. Но если у нас есть сочетание float s и int s, неструктурированное невозможно. Так genfromtxt что автоматически дал мне структурированный. Это правильно?

2. np.array([[1,2,3],[4,5,6]]) создает (2,3) int dtype массив. Вы должны использовать выражение like Out[11] для создания структурированного массива. Другими словами, это должен быть список кортежей с полностью указанным dtype .

3. Спасибо. и в чем причина np.genfromtxt(StringIO("1 2 3.0n 4 5 6.0"), dtype=None) , по которой получается полностью структурированный массив dtype ? Я просто хочу понять, когда мне нужно что-то делать Out[11] , потому что не похоже, что это всегда необходимо.

4. При dtype=None этом отмечается, что некоторые столбцы являются плавающими, а некоторые целыми. Чтобы сохранить этот микс, он должен использовать структурированный dtype. Мой предыдущий комментарий касался создания массива напрямую, с np.array помощью команды (а не через строку и genfromtxt ). Понимаете ли вы, что структурированные и неструктурированные массивы ведут себя по-разному при выполнении вычислений и индексации? Не экономьте на базовом numpy чтении.