Вам не нужно заполнить rowNums
итеративно:
In [93]: rowNums=np.zeros(10,dtype=[('RowID','f8')])
In [94]: for i in range(0,10):
....: rowNums['RowID'][i]=i
....:
In [95]: rowNums
Out[95]:
array([(0.0,), (1.0,), (2.0,), (3.0,), (4.0,), (5.0,), (6.0,), (7.0,),
(8.0,), (9.0,)],
dtype=[('RowID', '<f8')])
Просто назначить диапазон значений в поле:
In [96]: rowNums['RowID']=np.arange(10)
In [97]: rowNums
Out[97]:
array([(0.0,), (1.0,), (2.0,), (3.0,), (4.0,), (5.0,), (6.0,), (7.0,),
(8.0,), (9.0,)],
dtype=[('RowID', '<f8')])
rfn.merge_arrays
не должно быть медленным - если csvData.dtype
не имеет большой количество полей. Эта функция создает новый dtype, который объединяет поля двух входов, а затем копирует поле данных по полю. Для многих строк и всего нескольких полей это довольно быстро.
Но вы должны иметь возможность получить первоначальный заказ без добавления дополнительного поля.
А 2 поле 1d массив:
In [118]: x = np.array([(4,2),(1, 0), (0, 1),(1,2),(3,1)], dtype=[('x', '<i4'), ('y', '<i4')])
In [119]: i = np.argsort(x, order=('y','x'))
In [120]: i
Out[120]: array([1, 2, 4, 3, 0], dtype=int32)
In [121]: x[i]
Out[121]:
array([(1, 0), (0, 1), (3, 1), (1, 2), (4, 2)],
dtype=[('x', '<i4'), ('y', '<i4')])
То же значение теперь сортируется сначала на y
, то на x
.
In [122]: j=np.argsort(i)
In [123]: j
Out[123]: array([4, 0, 1, 3, 2], dtype=int32)
In [124]: x[i][j]
Out[124]:
array([(4, 2), (1, 0), (0, 1), (1, 2), (3, 1)],
dtype=[('x', '<i4'), ('y', '<i4')])
Назад к исходному порядку
Я мог бы добавить массив индекс строки в x
, а затем сделал то по этому вопросу. Но зачем добавлять его; почему бы не просто применять i
в отдельный массив:
In [127]: np.arange(5)[i]
Out[127]: array([1, 2, 4, 3, 0])
Но сортировка, что это так же, как сортировка i
.
merge_arrays
делает по существу следующее:
Союз DTYPE:
In [139]: dt=np.dtype(rowNums.dtype.descr+x.dtype.descr)
In [140]: y=np.zeros((5,),dtype=dt)
заполнить значения:
In [141]: y['RowID']=np.arange(5)
In [143]: for name in x.dtype.names:
y[name]=x[name]
In [144]: y
Out[144]:
array([(0.0, 4, 2), (1.0, 1, 0), (2.0, 0, 1), (3.0, 1, 2), (4.0, 3, 1)],
dtype=[('RowID', '<f8'), ('x', '<i4'), ('y', '<i4')])
И чтобы проверить мой argsort
из argsort
идеи:
In [145]: y[i]
Out[145]:
array([(1.0, 1, 0), (2.0, 0, 1), (4.0, 3, 1), (3.0, 1, 2), (0.0, 4, 2)],
dtype=[('RowID', '<f8'), ('x', '<i4'), ('y', '<i4')])
In [146]: np.argsort(y[i],order=('RowID'))
Out[146]: array([4, 0, 1, 3, 2], dtype=int32)
In [147]: j
Out[147]: array([4, 0, 1, 3, 2], dtype=int32)
Сортировка по-умолчанию RowID
такая же, как и сортировка по i
.
Любопытно merge_arrays
совсем немного медленнее, чем моя реконструкция:
In [163]: rfn.merge_arrays([rowNums,x],flatten=True)
Out[163]:
array([(0.0, 4, 2), (1.0, 1, 0), (2.0, 0, 1), (3.0, 1, 2), (4.0, 3, 1)],
dtype=[('RowID', '<f8'), ('x', '<i4'), ('y', '<i4')])
In [164]: timeit rfn.merge_arrays([rowNums,x],flatten=True)
10000 loops, best of 3: 161 µs per loop
In [165]: %%timeit
dt=np.dtype(rowNums.dtype.descr+x.dtype.descr)
y=np.zeros((5,),dtype=dt)
y['RowID']=rowNums['RowID']
for name in x.dtype.names:
y[name]=x[name]
10000 loops, best of 3: 38.4 µs per loop
есть ли причина, что вы загрузка CSV и делать свою работу исключительно в 'numpy' вместо того, чтобы использовать' pandas'? Для меня «pandas» кажется естественным выбором, и все тесты, которые я видел, показали, что «pandas» имеет превосходную производительность для синтаксического анализа csv. – root
Спасибо за подсказку. Раньше я не встречал панд. Я посмотрю ... –