【问题标题】:How to dump a large csv file to a table using pandas?如何使用 pandas 将大型 csv 文件转储到表中?
【发布时间】:2020-08-06 21:43:25
【问题描述】:

我有一个大于1 GBcsv 文件。通常这就是我使用pandascsv 转换为table 的方式。

import pandas as pd
from sqlalchemy import create_engine

file_path = "/path/to/test.csv"
df = pd.read_csv(file_path)

for col in df.columns:
    # convert each column values to numeric 
    df[col] = pd.to_numeric(df[col], errors='coerce')

engine = create_engine('postgresql://username:password@localhost:port/dbname')
df.to_sql("mytable", engine)

如您所见,我加载了csv 文件,对每个column 执行操作并将其转储到table

现在由于我的文件非常大,pandas 无法在data frame 中加载它。所以我在网上查找了一个解决方案,它谈到了以块的形式加载data 并执行操作Using pandas to efficiently read in a large CSV file without crashing。所以这就是我想出的

file_path = "/path/to/test.csv" 
chunksize = 100000
for chunk in pd.read_csv(file_path, chunksize=chunksize, iterator=True, low_memory=False):
    columns = chunk.columns

它给了我每个块的columns。那么块大小是否意味着它一次读取n 行?我不太清楚如何确保覆盖所有块并继续将data 附加到table,这样最后,我将所有data 转储到table 就像我一样csv 文件更小?

【问题讨论】:

    标签: python pandas postgresql csv


    【解决方案1】:

    iteratorchunksize 上的更新文档可在此处找到:Iterating through files chunk by chunk

    那么块大小是否意味着它一次读取n 行?

    是的。

    您使用chunksize 的代码大部分是正确的,您只需将每个块添加到您的数据框。

    如果您的所有列都是相同类型并且不需要任何特殊逻辑/类型,则转换整个 DataFrame 而不是逐列进行。或者,您可以将dtypes 指定为read_csv。但是,您将无法指定 'coerce',因此请保持原样。

    对于非常大的数据,最好分块进行整个读取、转换、to_sql。另请注意,在这种情况下使用low_memory=False 没有意义,请使用默认的True。无论如何,您稍后都会转换类型,因此混合类型推断(这可能会发生)无关紧要。

    engine = create_engine('postgresql://username:password@localhost:port/dbname')
    reader = pd.read_csv(file_path, chunksize=chunksize, low_memory=True)
    for rows in reader:
        df = pd.DataFrame(rows)
        # column conversions
        for col in df.columns:
            df[col] = pd.to_numeric(df[col], errors='coerce')
        # sql export
        df.to_sql("mytable", engine)
    

    【讨论】:

    • 向数据帧添加块不会增加内存消耗吗?还是对于每个块,我需要不断转储到数据库?
    • 对于 1 GB,您可以将其保存在内存中,然后转储到 DB。但是您提出了一个很好的观点,尤其是对于较大的尺寸。分块更好:读取、转换、to_sql。但是low_memory=False 没有意义。已通过更改编辑了我的答案。
    • 只是另一个问题。如果我有一个非常小的 csv 文件,我还能保持块大小相同吗?我打算使用此代码将任何大小的 csv 转换为表格。
    • 是的,当然。这也有效,因为如果它非常小,它将在一个循环中处理。因此,除了循环构造的 微秒 开销之外,它对小文件的工作效果与对大文件一样好。
    • 顺便说一句,我建议您尝试在 read_csv 中指定 dtypes 并检查您是否真的需要“强制”选项。 for col in df.columns: df[col] = pd.to_numeric... 是代码中效率最低的部分,因此仅在必要时使用它。如果你的dtypes都一样,也可以在df = pd.DataFrame(rows)之后使用df.astype()
    猜你喜欢
    • 2014-11-15
    • 2023-02-20
    • 2019-12-02
    • 1970-01-01
    • 2018-04-29
    相关资源
    最近更新 更多