在numpy中快速读取较小结构的ascii数据文件
我想从 .xsf 文件中读取一个数据网格(也就是一个三维的浮点数组)。这个文件格式的说明可以在这里找到:http://www.xcrysden.org/doc/XSF.html,具体是关于 BEGIN_BLOCK_DATAGRID_3D 这一部分。
问题是数据有五列,如果元素的总数 Nx*Ny*Nz 不能被 5 整除,那么最后一行的长度可能会不一样。因此,我无法使用numpy.genfromtxt()和numpy.loadtxt()这些函数来读取数据。
我写了一个子程序来解决这个问题,但速度非常慢(可能是因为它使用了紧密的循环)。我想读取的文件很大(超过 200 MB,200x200x200 = 8000000 个 ASCII 数字)。
有没有什么非常快速的方法可以在 Python/numpy 中读取这种不太友好的格式并转换成 ndarray?
xsf 数据网格的样子是这样的(以形状为 (3,3,3) 为例)
BEGIN_BLOCK_DATAGRID_3D
BEGIN_DATAGRID_3D_this_is_3Dgrid
3 3 3 # number of elements Nx Ny Nz
0.0 0.0 0.0 # grid origin in real space
1.0 0.0 0.0 # grid size in real space
0.0 1.0 0.0
0.0 0.0 1.0
0.000 1.000 2.000 5.196 8.000 # data in 5 columns
1.000 1.414 2.236 5.292 8.062
2.000 2.236 2.828 5.568 8.246
3.000 3.162 3.606 6.000 8.544
4.000 4.123 4.472 6.557 8.944
1.000 1.414 # this is the problem
END_DATAGRID_3D
END_BLOCK_DATAGRID_3D
1 个回答
0
我用Pandas和Numpy搞定了一些事情。Pandas会自动填补缺失数据中的nan值。
import pandas as pd
import numpy as np
df = pd.read_csv("xyz.data", header=None, delimiter=r'\s+', dtype=np.float, skiprows=7, skipfooter=2)
data = df.values.flatten()
data = data[~np.isnan(data)]
result = data.reshape((data.size/3, 3))
输出结果
>>> result
array([[ 0. , 1. , 2. ],
[ 5.196, 8. , 1. ],
[ 1.414, 2.236, 5.292],
[ 8.062, 2. , 2.236],
[ 2.828, 5.568, 8.246],
[ 3. , 3.162, 3.606],
[ 6. , 8.544, 4. ],
[ 4.123, 4.472, 6.557],
[ 8.944, 1. , 1.414]])