In [280]: txt=[' 0 : 16, 250 : 1 : 0.053 :RIG : DIS : 1 : 48, 220; 2
...: : 42, 241; 2 : 43, 251; 3 : 25, 266; 1 : 36, 287; 2 '
...: ]
In [282]: np.genfromtxt(txt,delimiter=':',dtype=None, encoding=None)
Out[282]:
array((0, ' 16, 250 ', 1, 0.053, 'RIG ', ' DIS ', 1, ' 48, 220; 2 ', ' 42, 241; 2 ', ' 43, 251; 3 ', ' 25, 266; 1 ', ' 36, 287; 2'),
dtype=[('f0', '<i8'), ('f1', '<U12'), ('f2', '<i8'), ('f3', '<f8'), ('f4', '<U4'), ('f5', '<U5'), ('f6', '<i8'), ('f7', '<U15'), ('f8', '<U15'), ('f9', '<U15'), ('f10', '<U15'), ('f11', '<U14')])
Это структурированный массив с 11 полями, представляющий собой целое число, строку и число с плавающей точкой Это потому, что dtype=None
говорит ему выводить тип d для каждого столбца.
Разделение на ,
создает массив из 7 столбцов (здесь 1d, потому что есть только одна строка ввода, но это будет 2d с большим количеством):
In [283]: np.genfromtxt(txt,delimiter=',',dtype=None, encoding=None)
Out[283]:
array(['0 : 16', ' 250 : 1 : 0.053 :RIG : DIS : 1 : 48',
' 220; 2 : 42', ' 241; 2 : 43', ' 251; 3 : 25',
' 266; 1 : 36', ' 287; 2'], dtype='<U42')
Но обратите внимание, это все строки.
genfromtxt
не принимает несколько разделителей, но принимает входные данные от всего, что передает ему строки.
Так что, если я определю функцию, которая заменяет разделители:
In [285]: def foo(astr):
...: return astr.replace(':',',').replace(';',',')
...:
...:
In [286]: np.genfromtxt([foo(a) for a in txt],delimiter=',',dtype=None, encoding
...: =None)
Out[286]:
array((0, 16, 250, 1, 0.053, 'RIG ', ' DIS ', 1, 48, 220, 2, 42, 241, 2, 43, 251, 3, 25, 266, 1, 36, 287, 2),
dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<i8'), ('f4', '<f8'), ('f5', '<U4'), ('f6', '<U5'), ('f7', '<i8'), ('f8', '<i8'), ('f9', '<i8'), ('f10', '<i8'), ('f11', '<i8'), ('f12', '<i8'), ('f13', '<i8'), ('f14', '<i8'), ('f15', '<i8'), ('f16', '<i8'), ('f17', '<i8'), ('f18', '<i8'), ('f19', '<i8'), ('f20', '<i8'), ('f21', '<i8'), ('f22', '<i8')])
Теперь я разбил входные данные на структурированный массив с 23 полями, снова смесью целых чисел, чисел с плавающей запятой и (меньших) строк.
genfromtxt
позволяет мне определить dtype
, который мог бы группировать подполя вместе.
Например, просто пытаюсь обработать первые 6 столбцов:
In [298]: dt = np.dtype([('f0','i'),('f1','i',2),('f2','i'),('f3','i'),('f4','U3
...: ')])
In [299]: np.genfromtxt([foo(a) for a in txt],delimiter=',',dtype=dt, encoding=N
...: one,usecols=range(6))
Out[299]:
array((0, [ 16, 250], 1, 0, 'RIG'),
dtype=[('f0', '<i4'), ('f1', '<i4', (2,)), ('f2', '<i4'), ('f3', '<i4'), ('f4', '<U3')])
Я сгруппировал '16,250'
в одно поле, содержащее 2 целых. Позже 48,220; 2,42,241; 2 'может вложить 3 поля (определенных с помощью'; '), и в пределах этих 2,2 и 1 подполей.
genfromtxt
допускает другую форму разделителя - фиксированную ширину поля.
Speedwise, genfromtxt
не предлагает никаких улучшений по сравнению с вашим собственным. Он по-прежнему должен читать каждую строку, разбивать ее и собирать значения в список списков. В конце он преобразует это в массив.
pandas
имеет более быстрое csv
устройство чтения, но этот случай может быть слишком сложным, чтобы использовать его. Параметр engine=python
заставляет его использовать более медленную версию Python.