我有一个按块构造的ASCII文件,如下所示(简化版本):
setContentView(mGameView);
我们可以忽略标题行,每个块都由定义时间步长的TS行开始,然后是一个长为ND的数据块。块中每个数据点的索引仅是值在块中的位置。数据块由“ TS”行分隔。
我想与Dask一起阅读,以便我可以处理非常大的文件。我想我需要使用dask.read_bytes,但是在这种情况下,我的分隔符是变量(即'TS 0 * \ n')加上每个块的时间步长值(即TS 0 180.00中的180)
关于这是否可能以及如何进行的一些指示将不胜感激。目标文件约为12GB。
答案 0 :(得分:0)
对于给定的数据样本,您可以执行以下操作:
head, parts = dask.bytes.read_bytes(infile, delimiter=b'\nTS 0', blocksize=30)
此处,head
包含文件的前导字节(对于这种情况,整个文件!通常由sample=
控制)。如果您还没有正则表达式,则查找全局元数据可能是最好的选择。
re.search(b'ND (\d+)', head).groups()[0]
b'4'
对于数据,您将需要类似以下的功能。我在这里假设数据帧输出。另外,我猜每一行TS之后有一行数据,因为这就是样本所具有的。此功能可能不够美观或效率很高,但可以完成工作
import numpy as np
import pandas as pd
import dask
@dask.delayed
def proc(bytes, meta):
if len(bytes) == 0:
return meta
parts = bytes.split(b'\nTS 0')
out = []
for part in parts:
if len(part) == 0:
continue
lines = part.split(b'\n')
timestep = float(lines[0].strip())
values = np.fromstring(lines[1], dtype=float, sep=' ')
out.append(pd.DataFrame({'timestep': timestep, 'values': values}))
return pd.concat(out)
meta = pd.DataFrame([], dtype=float, columns=['timestep', 'values'])
dd.from_delayed([proc(p, meta) for p in parts[0][1:]], meta=meta)
注意:
我们提供了meta
,因为某些块可能是空的(对于本例中的小块而言)。我们还跳过每个字节块末尾的空块。
第一个块包含标头,不应将其解析为数据(这是[1:]
选择)。如果它还包含数据,则需要额外的代码来处理(也许只是try / except解析块)
parts
是延迟字节列表的列表;理论上,一次调用中可能有多个输入文件。如何处理它们取决于每个文件是否都有标题,以及是否需要从每个文件中独立解析该信息。或者,可以将此处生成的数据帧连接起来。
计算这段代码,我得到
timestep values
0 0.0 1.0
1 0.0 2.0
2 0.0 3.0
3 0.0 4.0
0 180.0 1.1
1 180.0 2.1
2 180.0 3.1
3 180.0 4.1
0 360.0 1.2
1 360.0 2.2
2 360.0 3.2
3 360.0 4.2
0 540.0 1.3
1 540.0 2.3
2 540.0 3.3
3 540.0 4.3