读取制表符分隔的ASCII数据,变量之间用空行分隔

时间:2018-08-13 22:56:49

标签: python ascii data-science

我有一个烦人的数据集,我需要使用ASCII的python进行修改,其中包含6行标题,然后是一堆数据行(200万行)。格式如下:

2014     2     5  1200     0    29   349   277
2  32463.0020  32463.0020      1.0000   -145.5000      0.0000      0.0000
50.0000   -107.0000
1000   975   950   925   900   875   850   825   800   775   750   725
700   650   600   550   500   450   400   350   300   275   250   225
200   175   150   125   100
-6.63661    -6.63661    -6.76161    -6.76161    -6.83974    -6.55849    -6.55849    -6.12099
-5.93349    -5.90224    -5.73036    -5.55849    -5.71474    -5.60536    -5.71474    -5.71474
-5.76161    -5.76161    -5.83974    -5.83974    -5.83974    -5.73036    -5.60536    -5.51161
-5.32411    -5.35536    -5.19911    -5.18349    -4.87099    -4.57411    -4.23036    -3.74599
-3.76161    -3.76161    -3.91786    -3.91786    -4.30849    -4.43349    -5.10536    -6.37099

-5.79286    -5.91786    -6.32/411    -6.82411    -6.82411    -6.71474    -6.58974    -6.58974
-6.48036    -6.48036    -6.30849    -6.02724    -6.10536    -5.21474    -5.01161    -4.48036
-4.60536    -4.51161    -4.44911    -4.69911    -4.77724    -4.99599    -5.43349    -5.43349
-5.41786    -5.27724    -5.27724    -6.01161    -5.43349    -6.15224    -5.44911    -4.69911
-3.71474    -2.40224    -3.48036    -4.12099    -4.69911    -5.16786    -6.08974    -4.74599

前6行是标题信息,然后是一个变量的值巨大块,然后是一个换行符,然后是下一个变量的值。

我需要修改数据文件中的一个变量,而不要修改其他变量(修改就像将一个整数添加到每个值一样简单),但是我在努力弄清楚如何读取该文件中的工作每个数据块都作为python中的一个数组或值列表。我在网上找到的大多数资源都假设每一列都是一个单独的变量。有没有一种快速简便的方法可以在python中做到这一点?我想我会先检查一下这里,然后再自己动手做事。

谢谢!

2 个答案:

答案 0 :(得分:1)

假定数据文件为.txt的纯Python方法:

with open ("data.txt","r") as file_obj:
    data = file_obj.read().splitlines(True)

    variable_array = []
    for data_line in range (6, 11):
        data_line = data[data_line].split("    ")
        for item in data_line:
            item = item.strip()
            variable_array.append (item)

print (variable_array)

这将导致仅第一个块的数组,每个变量都是其自己的元素:

['-6.63661', '-6.63661', '-6.76161', '-6.76161', '-6.83974', '-6.55849', '-6.55849', 
'-6.12099', '-5.93349', '-5.90224', '-5.73036', '-5.55849', '-5.71474', '-5.60536', 
'-5.71474', '-5.71474', '-5.76161', '-5.76161', '-5.83974', '-5.83974', '-5.83974', 
'-5.73036', '-5.60536', '-5.51161', '-5.32411', '-5.35536', '-5.19911', '-5.18349', 
'-4.87099', '-4.57411', '-4.23036', '-3.74599', '-3.76161', '-3.76161', '-3.91786', 
'-3.91786', '-4.30849', '-4.43349', '-5.10536', '-6.37099']

该行:

for data_line in range (6, 11):

使用6和11定义第一个块所在的行的范围-如果数据块的模式一直到文件末尾都是完全连续的,则更改起来非常容易。您可以读取一个块,更改该块,读取下一个块,对其进行更改,依此类推。

还有许多更有效的方法(请参阅aydow的答案),但是该方法是纯python,完全没有外部依赖性。如果您不太关心效率,这是一个优先事项。

答案 1 :(得分:0)

Generators通常是管理复杂迭代的好方法。

此生成器读取数据文件,跳过前六行标题行,然后输出每个块中值的列表,假定这些块由空行分隔。

此生成器将值输出为字符串,因为尚不清楚应如何处理-6.32/411;修改生成器以生成所需的类型并不难。

def extract(path_to_file):
    with open(path_to_file) as f:
        values = []
        for idx, line in enumerate(f):
            if idx < 6:
                # Ignore header lines
                continue
            if line.strip():
                # Add the values in this line to the current
                # values list.
                values.extend(line.split())
            else:
                # Blank line, so output values and
                # clear the list.
                yield values
                del values[:]
        # Yield the final set of values, assuming
        # the last line of the file is not blank.
        yield values


values = extract('data.dat')
for item in values:
    print(item)

输出:

['-6.63661', '-6.63661', '-6.76161', '-6.76161', '-6.83974', '-6.55849', '-6.55849', '-6.12099', '-5.93349', '-5.90224', '-5.73036', '-5.55849', '-5.71474', '-5.60536', '-5.71474', '-5.71474', '-5.76161', '-5.76161', '-5.83974', '-5.83974', '-5.83974', '-5.73036', '-5.60536', '-5.51161', '-5.32411', '-5.35536', '-5.19911', '-5.18349', '-4.87099', '-4.57411', '-4.23036', '-3.74599', '-3.76161', '-3.76161', '-3.91786', '-3.91786', '-4.30849', '-4.43349', '-5.10536', '-6.37099']
['-5.79286', '-5.91786', '-6.32/411', '-6.82411', '-6.82411', '-6.71474', '-6.58974', '-6.58974', '-6.48036', '-6.48036', '-6.30849', '-6.02724', '-6.10536', '-5.21474', '-5.01161', '-4.48036', '-4.60536', '-4.51161', '-4.44911', '-4.69911', '-4.77724', '-4.99599', '-5.43349', '-5.43349', '-5.41786', '-5.27724', '-5.27724', '-6.01161', '-5.43349', '-6.15224', '-5.44911', '-4.69911', '-3.71474', '-2.40224', '-3.48036', '-4.12099', '-4.69911', '-5.16786', '-6.08974', '-4.74599']