6

我是 python 新手,正在尝试从文件中读取“块”数据。该文件是这样写的:

# Some comment
# 4 cols of data --x,vx,vy,vz
# nsp, nskip =           2          10


#            0   0.0000000


#            1           4
 0.5056E+03  0.8687E-03 -0.1202E-02  0.4652E-02
 0.3776E+03  0.8687E-03  0.1975E-04  0.9741E-03
 0.2496E+03  0.8687E-03  0.7894E-04  0.8334E-03
 0.1216E+03  0.8687E-03  0.1439E-03  0.6816E-03


#            2           4
 0.5056E+03  0.8687E-03 -0.1202E-02  0.4652E-02
 0.3776E+03  0.8687E-03  0.1975E-04  0.9741E-03
 0.2496E+03  0.8687E-03  0.7894E-04  0.8334E-03
 0.1216E+03  0.8687E-03  0.1439E-03  0.6816E-03


#          500  0.99999422


#            1           4
 0.5057E+03  0.7392E-03 -0.6891E-03  0.4700E-02
 0.3777E+03  0.9129E-03  0.2653E-04  0.9641E-03
 0.2497E+03  0.9131E-03  0.7970E-04  0.8173E-03
 0.1217E+03  0.9131E-03  0.1378E-03  0.6586E-03

and so on

现在我希望能够从这些块中指定和读取一个数据块。我numpy.loadtxt('filename',comments='#')用来读取数据,但它一次性加载整个文件。我在网上搜索,有人为 numpy io 例程创建了一个补丁来指定读取块,但它不在主流 numpy 中。

在 gnuplot 中选择数据块要容易得多,但我必须编写例程来绘制分布函数。如果我能弄清楚阅读特定的块,那么在 python 中会容易得多。此外,我正在将我所有的可视化代码从 IDL 和 gnuplot 转移到 python,因此将所有内容都放在 python 中而不是将东西分散在多个包中会很好。

我想过从 python 中调用 gnuplot,将一个块绘制到一个表中,并将输出分配给 python 中的某个数组。但我还在开始,我无法弄清楚这样做的语法。

解决这个问题的任何想法,指针都会有很大帮助。

4

2 回答 2

5

快速基本阅读:

>>> def read_blocks(input_file, i, j):
    empty_lines = 0
    blocks = []
    for line in open(input_file):
        # Check for empty/commented lines
        if not line or line.startswith('#'):
            # If 1st one: new block
            if empty_lines == 0:
                blocks.append([])
            empty_lines += 1
        # Non empty line: add line in current(last) block
        else:
            empty_lines = 0
            blocks[-1].append(line)
    return blocks[i:j + 1]

>>> for block in read_blocks(s, 1, 2):
    print '-> block'
    for line in block:
        print line


-> block
 0.5056E+03  0.8687E-03 -0.1202E-02  0.4652E-02
 0.3776E+03  0.8687E-03  0.1975E-04  0.9741E-03
 0.2496E+03  0.8687E-03  0.7894E-04  0.8334E-03
 0.1216E+03  0.8687E-03  0.1439E-03  0.6816E-03
-> block
 0.5057E+03  0.7392E-03 -0.6891E-03  0.4700E-02
 0.3777E+03  0.9129E-03  0.2653E-04  0.9641E-03
 0.2497E+03  0.9131E-03  0.7970E-04  0.8173E-03
 0.1217E+03  0.9131E-03  0.1378E-03  0.6586E-03
>>> 

现在我想你可以使用 numpy 来阅读这些行......

于 2012-05-09T17:23:57.517 回答
1

以下代码应该可以帮助您入门。您可能需要 re 模块。

您可以使用以下命令打开文件进行阅读:

f = open("file_name_here")

您可以使用一次一行读取文件

line = f.readline()

要跳转到以“#”开头的下一行,您可以使用:

while not line.startswith("#"):
    line = f.readline()

要解析看起来像“# i j”的行,可以使用以下正则表达式:

is_match = re.match("#\s+(\d+)\s+(\d+)",line)
if is_match:
    i = is_match.group(1)
    j = is_match.group(2)

有关这方面的更多信息,请参阅“re”模块的文档。

要解析一个块,您可以使用以下代码:

block = [[]] # block[i][j] will contain element i,j in your block
while not line.isspace(): # read until next blank line
    block.append(map(float,line.split(" "))) 
    # splits each line at each space and turns all elements to float
    line = f.readline()

然后,您可以根据需要将块转换为 numpy 数组:

block = np.array(block)

前提是您已将 numpy 导入为 np. 如果要读取 i 和 j 之间的多个块,只需将上面读取一个块的代码放入一个函数中并多次使用即可。

希望这可以帮助!

于 2012-05-09T17:05:03.927 回答