NumPy:使用loadtxt或genfromtxt读取衣衫agged的结构

|| 我需要将ASCII文件读入Python,该文件的摘录如下所示:
E     M S T   N...
...
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 12373
理想情况下,以上内容应遵循NumPy模式:
array([(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, 12373))], 
      dtype=[(\'E\', \'<i4\'), (\'M\', \'<i4\'), (\'S\', \'<i4\'), (\'T\', \'<i4\'), (\'N\', \'|O4\')])
最后一个对象
N
是一个
tuple
,其整数在2到8之间。 我想使用
np.loadtxt
np.genfromtxt
加载这个衣衫structure的结构,除了我不确定是否可以这样做。有内置的技巧,还是我需要自定义循环分割?     
已邀请:
据我所知,您确实需要一个自定义的\“ 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))]
    

要回复问题请先登录注册