在numpy中快速读取较小结构的ascii数据文件

2 投票
1 回答
641 浏览
提问于 2025-04-17 20:47

我想从 .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]])

撰写回答