如何在Python中读取包含大量未排序表格数据的大文件?

如何在Python中读取包含大量未排序表格数据的大文件?,python,pandas,numpy,Python,Pandas,Numpy,我有一个大的CSV文件(>100GB),我想把它读入内存,然后分块处理数据。我有两个限制: 显然,我无法将整个文件读入内存。我的机器上只有大约8GB的内存 数据是表格形式的,没有顺序。我需要分组阅读数据 股票行情 日期 字段1 字段2 字段3 AAPL 20201201 0 0 0 AAPL 20201202 0 0 0 AAPL 20201203 0 0 0 AAPL 20201204 0 0 0 NFLX 20201201 0 0 0 NFLX 20201202 0 0 0 NFLX 202

我有一个大的CSV文件(>100GB),我想把它读入内存,然后分块处理数据。我有两个限制:

  • 显然,我无法将整个文件读入内存。我的机器上只有大约8GB的内存
  • 数据是表格形式的,没有顺序。我需要分组阅读数据
  • 股票行情 日期 字段1 字段2 字段3 AAPL 20201201 0 0 0 AAPL 20201202 0 0 0 AAPL 20201203 0 0 0 AAPL 20201204 0 0 0 NFLX 20201201 0 0 0 NFLX 20201202 0 0 0 NFLX 20201203 0 0 0 NFLX 20201204 0 0 0 这个怎么样:

  • 打开文件
  • 循环读取行:对于读取的每行:
    • 解析股票代码
    • 如果尚未完成:
      • 创建并打开该股票代码的文件(“股票代码文件”)
      • 附加到某个dict,其中key=ticker,value=file句柄
    • 将该行写入ticker文件
  • 关闭ticker文件和原始文件
  • 处理每个单独的ticker文件

  • 我将研究两种选择

    Vaex和Dask

    Vaex似乎完全专注于您的需求。延迟处理和非常大的数据集。检查他们的github。然而,您似乎需要将文件转换为hdf5,这可能需要花费一些时间


    就达斯克而言,我不指望成功。Dask主要专注于分布式计算,我不确定它是否可以懒洋洋地处理大文件。但是你可以试试看。

    这种方法是纯粹的熊猫。它将使用两个函数:一个用于计算索引,一个用于读取一个块。我会说,如果你的小组中有任何一个不符合记忆的话,那就彻底失败了(但考虑到你的标准,这些小组必须一次读一个,我会说这肯定是一个符合的猜测)

    您需要在索引的词汇表上循环(根据第一个函数计算),以读取整个数据帧

    希望这将有助于。。。(毫不犹豫地根据您的需要调整chunksize的默认值)


    pandas的csv阅读器有一个chunksize参数是的,但这取决于行数,而不是值。试试这个解决方案:我建议看看Dask:,它完全是为您提到的核心需求而设计的,并且从实用的角度讲:只需购买更多的Ram,您考虑过了吗?
    import pandas as pd
    
    def compute_indexes(url, cols_indexes=[], chunksize=100000, **kwargs):
        """
        Returns a dictionnary
        Keys are the pseudo indexes of the dataframe 
        Values are lists of indexes corresponding to this index
        """
        iterator = pd.read_csv(
                url, 
                usecols=cols_indexes, 
                chunksize=chunksize,
                **kwargs)
        
        dict_groups = dict()
        for df in iterator:
            groups_present = df.drop_duplicates(keep="first").values.tolist()
            df.reset_index(drop=False, inplace=True)
            df.set_index(cols_indexes, inplace=True)
            for group in groups_present:
                group = tuple(group)
                if group not in dict_groups:
                    dict_groups[group] = []
                try:
                    dict_groups[group] += df.loc[group]['index'].tolist()
                except TypeError:
                    #only one row
                    dict_groups[group] += [df.loc[group]['index']]
                    
        return dict_groups
    
    def read_csv_group(url, dict_groups, which_group, **kwargs):
        if isinstance(which_group, list):
            which_group = tuple(which_group)
        rows = dict_groups[which_group]
        def skip_rows(x):
            if x == 0:
                return False
            elif x in {x+1 for x in rows}:
                return False
            else:
                return True
        df = pd.read_csv(url, skiprows=skip_rows, **kwargs)
        return df
        
    URL = "./dummy.csv"
    indexes = ['Ticker', 'Date']
    kwargs = {'dtype':{'Ticker':str, 'Date':int})
    dict_groups = compute_indexes(URL, indexes, chunksize=100000, **kwargs)
    df_one_group = read_csv_group(URL, dict_groups, ('AAPL', 20201201), **kwargs)