Numpy:使用savetxt()导出时使用genfromtxt()中的dtype

时间:2015-04-09 23:17:11

标签: python numpy

numpy.genfromtxt(infile, dtype=None)可以很好地确定输入文件每列中的数字格式。在使用numpy.savetxt()保存数据文件时,我们如何使用这些已确定的相同类型? Savetxt使用非常不同的格式语法。

indata = '''
    1000  254092.500 1630087.500  9144.00  9358.96   214.96
     422  258667.500 1633267.500  6096.00  6490.28   394.28
      15  318337.500 1594192.500  9144.00 10524.28  1380.28
     -15  317392.500 1597987.500  6096.00  4081.26 -2014.74
     -14  253627.500 1601047.500 21336.00 20127.51 -1208.49
END
'''

import numpy as np
header = 'Scaled_Residual,X,Y,Local_Std_Error,Vertical_Std_Error,Unscaled_Residual'
data = np.genfromtxt(indata, names=header, dtype=None,
    comments='E') #skip 'END' lines

print data.dtype

发射:

[('Scaled_Residual', '<i4'), ('X', '<f8'), ('Y', '<f8'), ('Local_Std_Error', '<f8'), ('Vertical_Std_Error', '<f8'), ('Unscaled_Residual', '<f8')]

那么如何优雅地重建data.dtype以使其符合savetxt(... fmt='%i, %f, ...'语法而无需手动单步执行?是否存在 savefromgentxt()必然结果?

fmt=data.dtype的简单而有希望的尝试完全失败了。 ; - )

np.savetxt('test.csv', data, header=header, delimiter=',',
    fmt=data.dtype)

结果:

  ...snip...\numpy\lib\npyio.py", line 1047, in savetxt
    fh.write(asbytes(format % tuple(row) + newline))
UnboundLocalError: local variable 'format' referenced before assignment

1 个答案:

答案 0 :(得分:1)

fmt应该是格式字符串或字符串列表。请参阅savetxt文档中的示例。它不是dtype

np.savetxt('test.csv',data, fmt='%10s')

获得90%的胜利:

  1000   254092.5  1630087.5     9144.0    9358.96     214.96
   422   258667.5  1633267.5     6096.0    6490.28     394.28
    15   318337.5  1594192.5     9144.0   10524.28    1380.28
   -15   317392.5  1597987.5     6096.0    4081.26   -2014.74
   -14   253627.5  1601047.5    21336.0   20127.51   -1208.49

通过为每列指定一个带小数位数等的fmt字符串,你会更接近。

np.savetxt('test.csv',data, fmt='%10d  %10.3f %10.3f %10.2f %10.2f %10.2f')

做得更好。您可以进一步调整fmt

savetxt的Python代码并不复杂。我建议看一下。

dtype生成更多爱好者的问题是,没有更多信息。

In [154]: [x[1] for x in data.dtype.descr]
Out[154]: ['<i4', '<f8', '<f8', '<f8', '<f8', '<f8']

比较这些格式:

In [158]: '%i %f %f %f %f %f'%tuple(data[0])
Out[158]: '1000 254092.500000 1630087.500000 9144.000000 9358.960000 214.960000'

In [159]: '%s %s %s %s %s %s'%tuple(data[0])
Out[159]: '1000 254092.5 1630087.5 9144.0 9358.96 214.96'

In [160]: ' '.join(['%10s']*6)%tuple(data[0])
Out[160]: '      1000   254092.5  1630087.5     9144.0    9358.96     214.96'

dtype信息的简单翻译:

def foo(astr):
    if 'i' in astr:
        return '%10i'
    elif 'f' in astr:
        return '%10f'
[foo(x[1]) for x in data.dtype.descr]
# ['%10i', '%10f', '%10f', '%10f', '%10f', '%10f']

您还可以使用dtype名称生成标题行。