我有一个csv文件,中间有不同的标题(实际上是行)
COMMENT1
COMMENT2
1,2,3,4
1,2,3,4
0 /END OF A DATA
1,2,3,4,5,6,7
1,2,3,4,5,6,7
0 /END OF B DATA
我可以使用read_csv()中的钩子来获取这些部分之间的数据吗?请注意,这是一个大文件,我想在不将整个文件加载到内存中的情况下进行一些统计
df = dask.dataframe.read_csv('datafile.csv',skiprows = 3,header = None,quotechar =“'”)
我可以单独加载block1或block2(再次不完全加载到内存中)吗?
谢谢,
答案 0 :(得分:0)
您可以使用函数read_bytes加载数据 - 这将读取您的文件并根据任意分隔符将其转换为块。
from dask.bytes import read_bytes
sample, chunks = read_bytes(mypath, delimiter=b'\n0 /END')
这将生成延迟对象,其中每个对象都包含一个或多个数据块。您需要提供一个适当的函数来处理每个块并从每个块返回数据帧。如下所示:
def process_chunk(data):
blocks = data.decode().split("\n0 /END")
out = []
for data in blocks:
data = '\n'.join(line for line in data.split('\n')
if not (line.startswith('COMMENT') or
line.startswith(' OF ')))
if data:
out.append(pd.read_csv(io.StringIO(data), header=None))
return out
chunks = chunks[0] # if only one file
results = [dask.delayed(process_chunk)(ch) for ch in chunks]
Dask将逐块处理您的数据,而不是将所有内容加载到 记忆一下。
您可以使用dask.compute()
评估results
的一个或多个元素,或者在调用compute()
之前向其应用更多delayed个函数,以便并行处理它们。