Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Dask read_csv:跳过定期观察的行_Python_Dask - Fatal编程技术网

Python Dask read_csv:跳过定期观察的行

Python Dask read_csv:跳过定期观察的行,python,dask,Python,Dask,我想使用Dask在多个时间步读取原子坐标的大文件。该格式称为XYZ文件,如下所示: 3. 时间步1 C 9.5464696279 5.2523477968 4.4976072664 C 10.6455075132 6.0351186102 4.0196547961 C 10.2970471574 7.3880736108 3.6390228968 3. 时间步2 C 9.5464696279 5.2523477968 4.4976072664 C 10.6455075132 6.0351186

我想使用Dask在多个时间步读取原子坐标的大文件。该格式称为XYZ文件,如下所示:


3.
时间步1
C 9.5464696279 5.2523477968 4.4976072664
C 10.6455075132 6.0351186102 4.0196547961
C 10.2970471574 7.3880736108 3.6390228968
3.
时间步2
C 9.5464696279 5.2523477968 4.4976072664
C 10.6455075132 6.0351186102 4.0196547961
C 10.2970471574 7.3880736108 3.6390228968

第一行包含原子数,第二行只是一条注释。 然后,列出原子的名称和位置。 列出所有原子后,在下一个时间步骤中重复相同的操作

我现在想通过
dask.dataframe.read\u csv
加载这样的轨迹。 然而,我不知道如何跳过包含原子数和注释的周期性的注释行。这真的可能吗

编辑

可以通过以下方式将此格式读入数据帧:

atom_nr = 3

def skip(line_nr):
    return line_nr % (atom_nr + 2) < 2


pd.read_csv(xyz_filename, skiprows=skip, delim_whitespace=True,
            header=None)
atom\u nr=3
def skip(行编号):
返回线数量%(原子数量+2)<2
pd.read_csv(xyz_文件名,skiprows=skip,delim_空格=True,
页眉=无)
但看起来Dask数据帧不支持向skiprows传递函数

编辑2: 奥克林先生的答案是有效的!为了完整起见,我写下了我使用的完整代码

from io import BytesIO

import pandas as pd
import dask.bytes
import dask.dataframe
import dask.delayed


atom_nr = ...
filename = ...


def skip(line_nr):
    return line_nr % (atom_nr + 2) < 2


def pandaread(data_in_bytes):
    pseudo_file = BytesIO(data_in_bytes[0])
    return pd.read_csv(pseudo_file, skiprows=skip, delim_whitespace=True,
                       header=None)

bts = dask.bytes.read_bytes(filename, delimiter=f"{atom_nr}\ntimestep".encode())
dfs = dask.delayed(pandaread)(bts)

sol = dask.dataframe.from_delayed(dfs)
sol.compute()
从io导入字节io
作为pd进口熊猫
导入dask.bytes
导入dask.dataframe
输入数据延迟
原子数=。。。
文件名=。。。
def skip(行编号):
返回线数量%(原子数量+2)<2
def pandaread(数据以字节为单位):
伪文件=字节(数据以字节[0]为单位)
返回pd.read\u csv(伪文件,skiprows=skip,delim\u空格=True,
页眉=无)
bts=dask.bytes.read_bytes(文件名,分隔符=f“{atom\u nr}\ntimestep.encode())
dfs=数据延迟(泛区域)(bts)
sol=dask.dataframe.from_延迟(dfs)
sol.compute()
剩下的唯一问题是:如何告诉dask只计算前n帧?目前看来,完整的轨迹已被读取。

简短回答 不,pandas.read_csv和dask.dataframe.read_csv都不提供这种功能(据我所知)

长话短说 如果您可以编写代码将其中一些数据转换为pandas数据帧,那么您可以使用

一般来说,这可能类似于以下内容:

values = read_bytes('filenames.*.txt', delimiter='...', blocksize=2**27)
dfs = [dask.delayed(load_pandas_from_bytes)(v) for v in values]
df = dd.from_delayed(dfs)
每个dfs大致对应于数据的
blocksize
字节(直到下一个分隔符)。您可以控制分区使用此块大小时的精细程度。如果需要,您也可以只选择其中的几个
dfs
对象,以获取较小的数据部分

dfs = dfs[:5]  # only the first five blocks of `blocksize` data 

我有一个后续问题:是否可以限制读取的数据帧数量?当我尝试上面的代码时(参见编辑2),dask将始终尝试读取完整的文件。