【问题标题】:How can I shuffle the rows of a large csv file and write the result to a new csv file without using too much memory?如何在不使用太多内存的情况下打乱大型 csv 文件的行并将结果写入新的 csv 文件?
【发布时间】:2020-01-18 06:35:14
【问题描述】:

所以如果我有一个csv文件如下:

User  Gender
 A    M
 B    F
 C    F

然后我想写另一个 csv 文件,其中的行像这样打乱(例如):

User  Gender
 C    F
 A    M
 B    F

我的问题是我不知道如何随机选择行并确保我从原始 csv 文件中获取每一行。作为参考,我的 csv 文件大约为 3gb。如果我将整个数据集加载到数据框中并使用随机包对其进行洗牌,我的电脑会由于 RAM 的使用而崩溃。

【问题讨论】:

    标签: python-3.x csv


    【解决方案1】:

    可能最简单(也是最快)的方法是在 bash 中使用 shuf

    shuf words.txt > shuffled_words.txt
    

    (我知道您要求提供 Python 解决方案,但我认为这仍然是一个更好的答案)

    通过 Python 以编程方式完成:

    import sh
    sh.shuf("words.txt", out="shuffled_words.txt")
    

    【讨论】:

    • sh.shuf 到底是做什么的?我似乎找不到关于它的文档。
    • @mrnovice sh 只是 bash 命令的包装器。所以sh. 之后的所有内容都将是一个 bash shell 命令。
    • 我尝试使用它,但出现错误说 sh 仅在 mac 和 linux 上受支持(我使用的是 windows)
    • @PascalVKooten 如果我的 CSV 有标题并且我不希望标题被打乱怎么办?
    • 如果.csv文件有标题怎么办?如何洗牌除第一行以外的所有内容?
    【解决方案2】:

    您可以将 chunk_size 参数用于块中的 csv

    df_chunks = pandas.read_csv("your_csv_name.csv", chunk_size=10)

    然后你可以只打乱块,所以它占用更少的内存

    for chunk in df_chunks:
        do stuff
    

    然后您可以将它们连接起来并将其保存到另一个 csv 中:

    new_df = pandas.concat(new_chunks)
    new_df.to_csv("your_new_csv_name.csv")
    

    如果您有内存问题,在创建 new_chunks 时不要忘记擦除旧的,因为您不希望它们无缘无故地留在 RAM 中,您可以使用 chunk=None

    【讨论】:

    • 我认为这个解决方案不适用于我的数据集,因为有两类数据,一类位于文件的上半部分,另一类位于下半部分。所以这个方法不会在这两个类别之间正确地洗牌。抱歉,我可能应该在我的问题中包含这些信息。
    【解决方案3】:
    • 通过将文件读取一次作为随机访问或内存映射文件,创建一个行数组作为行开始的文件位置。该数组有一个带有文件长度的额外条目, 所以 i 行包含字节 [array[i], array[i+1]>
    • 随机排列索引 0 .. 行数 - 1。
    • 现在您可以使用随机访问定位(查找)来读取行缓冲区。

    【讨论】:

    • 假设我的 csv 文件有 1000 行(不包括标题)。然后你提到的这个数组将存储数字 1 到 1000,最后会有一个数字 1000 的额外条目。然后我打乱这个数组,不包括最后一个条目。到目前为止这是正确的吗?我不太明白你所说的随机访问定位是什么意思。
    • 不,您需要一个置换数组来存储 1 到 1000 的索引(如果基于零的索引,则为 0 到 999)。伪代码:for j in 1 to 1000, i = permutation[j]; output line (i)
    猜你喜欢
    • 2019-08-10
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    • 2021-10-30
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多