【问题标题】:Concatenate 10000 dataframes from loop in groups of 100 to one big dataframe and save to csv/txt-file将 10000 个循环中的 1000 个数据帧以 100 个为一组连接到一个大数据帧并保存到 csv/txt 文件
【发布时间】:2020-08-31 09:35:45
【问题描述】:

我正在处理构建股票和如此大的数据框。我正在对 1000 个建筑物的 10000 个库存进行输入参数采样(因此,如果每个建筑物都是 csv 文件中的 1 行,则写入 csv 文件大约需要 10000000 行)。 为了执行此操作(在 Python 中不会出现 MemoryError)并为模拟程序准备文件,我需要将这些股票组合成更小的部分(而不是一个大文件),例如一次 100 只股票 1000 只。知道怎么做吗?

我准备了一个小例子,其中我有一个原始数据框,我在循环中覆盖了一个列。 最后,我将所有数据帧(在循环中生成)堆叠到一个大数据帧中(其中包含原始数据帧的 x 倍,并在此处和那里进行更改。而不是将所有内容堆叠到一个大 df 中并将其保存到 csv,我想一次堆叠 100 只股票。

现在我将所有库存堆叠在一个大 df 中,然后将其拆分为带有额外“ID”列的部分。有没有办法在这个过程中做到这一点(想象我需要总共需要 1000 或 100000 只股票)?计算并堆叠 100 只股票 -> 将它们保存到 csv -> 计算并堆叠接下来的 100 只股票 -> 将它们保存到 csv ...

试用过的代码:

import pandas as pd

df_or = pd.DataFrame({"Case": [1,2,3,4,5,6],  
                         "A": [3,5,2,8,4,1],       
                         "B": [10,12,24,8,57,84]})

print(df_or)

total = []

for i in range(0,1000):
    df = df_or.copy()
    df.loc[:, 'A'] = df_or.loc[:, 'A'].mul(i)   
    df.loc[:, 'ID'] = df.loc[:,'Case'] + i*100000
    print(df)

    total.append(df)

total = pd.concat(total)
total = total.sort_values('ID')

for i in range(0, 10):

    stocks = total[((i) * 100 * 100000 <= total['ID']) & (total['ID'] <= (i + 1) * 100 * 100000)]

    stocks.to_csv('stack100_' + str(i) + '.csv', sep=',', index=False)


【问题讨论】:

    标签: python pandas concat


    【解决方案1】:

    如果你要写的文件少于一千个,你可以同时打开它们;获取数据后,将每一行写入相应的文件。

    您需要将打开的文件保存在字典或类似文件中,这样您就可以将每一行写入正确的文件,最后您可以将它们全部关闭。

    类似:

    from contextlib import ExitStack
    import pandas as pd
    
    df_or = pd.DataFrame({"Case": [1,2,3,4,5,6],
                             "A": [3,5,2,8,4,1],
                             "B": [10,12,24,8,57,84]})
    
    with ExitStack() as stack:
    
        files = [
            stack.enter_context(open('stack100_' + str(j) + '.csv', 'w'))
            for j in range(0, 10)
        ]
    
        for i in range(0,1000):
            df = df_or.copy()
            df.loc[:, 'A'] = df_or.loc[:, 'A'].mul(i)
            df.loc[:, 'ID'] = df.loc[:,'Case'] + i*100000
    
            for j in range(0, 10):
                stocks = df[(
                    (j) * 100 * 100000
                    <= total['ID']) & (total['ID']
                    <= (j + 1) * 100 * 100000
                )]
                stocks.to_csv(files[j], sep=',', index=False)
    
            del stocks, df
    

    【讨论】:

    • 这是真的吗?我想这取决于您总共必须写入文件的数据大小?是的,写了 20.000.000 行,我昨天遇到了 MemoryError(我当时尝试了一个文件)所以我想拆分和批量保存是要走的路(也适用于未来更大的写作任务)。
    • 逐行工作意味着您在任何时候都只会有几行内存,因此您不会遇到问题。一旦你读入一行(或一小批),再次写出来以释放空间。
    • 我添加了一个示例,您可以如何翻译代码。
    【解决方案2】:

    您可以在附加模式下打开文件,然后将文件写入其中。

    import pandas as pd
    
    df = pd.read_csv("abalone.csv")
    
    with open("output.csv", 'a') as outf:
        df.to_csv(outf)
    

    通过这种方式,您可以一次读取每个文件,汇总并保存到文件中。一次只有一个文件在内存中。

    如果您以后只分批分析文件,我建议考虑在此步骤保存到这些批处理中,这样您的文件就更易于管理了。

    【讨论】:

    • 有趣的评论。我得试试看效果如何。
    • 您还可以关闭写入​​标题,除了第一个文件保存之外,您需要对所有内容执行此操作。
    猜你喜欢
    • 2016-10-05
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-12
    • 1970-01-01
    相关资源
    最近更新 更多