Насколько мне известно, вам нужен пользовательский метод "split-cast" для цикла.
Фактически, NumPy может читать вложенные структуры, подобные вашей, но они должны иметь фиксированную форму, как в
numpy.loadtxt('data.txt', dtype=[ ('time', np.uint64), ('pos', [('x', np.float), ('y', np.float)]) ])
При попытке прочитать данные с нужным вам dtype, NumPy считывает только первое число каждого кортежа:
dt=[('E', '<i4'), ('M', '<i4'), ('S', '<i4'), ('T', '<i4'), ('N', '|O4')]
print numpy.loadtxt('data.txt', dtype=dt)
, таким образом печатая
[(9998, 1, 1, 128, '10097')
(9999, 1, 1, 128, '10098')
(10000, 1, 1, 128, '10099')…]
Итак, я бы сказал, что нужно пойти дальше и использовать цикл for вместо numpy.loadtxt()
.
Вы также можете использовать промежуточный подход, который может быть быстрее: вы позволяете NumPy загрузить файл с вышеуказанным кодом, а затемвы вручную «исправляете» поле 'N':
dt=[('E', '<i4'), ('M', '<i4'), ('S', '<i4'), ('T', '<i4'), ('N', '|O4')]
arr = numpy.loadtxt('data.txt', dtype=dt) # Correctly reads the first 4 columns
with open('data.txt') as input_file:
for (line_num, line) in enumerate(input_file):
arr[line_num]['N'] = tuple(int(x) for x in line.split()[4:]) # Manual setting of the tuple column
Этот подход может быть быстрее, чем анализ всего массива в цикле for.Это дает желаемый результат:
[(9998, 1, 1, 128, (10097, 10098, 10199, 10198, 20298, 20299, 20400, 20399))
(9999, 1, 1, 128, (10098, 10099, 10200, 10199, 20299, 20300, 20401, 20400))
(10000, 1, 1, 128, (10099, 10100, 10201, 10200, 20300, 20301, 20402, 20401))
(10001, 1, 2, 44, (2071, 2172, 12373, 12272))
(10002, 1, 2, 44, (2172, 2273, 12474, 1237))]