繁体   English   中英

Pandas memory 使用和 memory 分配

[英]Pandas memory usage and memory allocation

我正在尝试使用 pandas 分析一个大的 csv (csv 是 ~3GB 和 ~600 万行)(我的计算机有 32GB 的 RAM 内存,我无法将其加载到大块中)。 我可以毫无问题地阅读 csv,但是一旦我开始清理文件,整个脚本就会崩溃。 Monitoring the memory usage of my computer I found that just to have the csv stored in a pandas DataFrame 50% of my RAM (18GB) is used. 当我开始修改 DataFrame 时,memory 的使用率飙升至 100% 并导致我的脚本崩溃。 使用 DataFrame 方法memory_usage(deep=True)我发现我的 DataFrame 对于 pandas 是 3GB。 但是 pandas 怎么可能告诉我我的变量是 3GB 而我的 memory 使用量是 18GB(可能是 13GB,因为操作系统使用了 %GB)?

这是一个例子:

raw = pd.read_csv("db.csv", sep="\t", on_bad_lines="skip", dtypes="object")

remove_invalid_ateco = lambda df_: df_[df_.ateco.str.contains("\.")]
months_diff = lambda a, b: 12 * (a.year - b.dt.year) + (a.month - b.dt.month)
raw.query(
            "~piva.isnull() and"
            "~code.isnull() and "
            "provincia_cd.str.len() == 2"
        )
        .pipe(remove_invalid_ateco)
        .assign(
            # Float
            roe=lambda df_: df_.roe.str.replace(",", "."),
            roi=lambda df_: df_.roi.str.replace(",", "."),
            ros=lambda df_: df_.ros.str.replace(",", "."),
            longitudine_dd=lambda df_: df_.longitudine_dd.str.replace(",", "."),
            latitudine_dd=lambda df_: df_.latitudine_dd.str.replace(",", "."),
            sfin=lambda df_: df_.sfin.str.replace(",", "."),
            cap_del=lambda df_: df_.cap_del.str.replace(
                ",", "."
            ),
            cap_sott=lambda df_: df_.cap_sott.str.replace(
                ",", "."
            ),
            cap_vers=lambda df_: df_.cap_vers.str.replace(",", "."),
            eq_ec_1=lambda df_: df_.eq_ec_1.str.replace(",", "."),
            eq_eff_1=lambda df_: df_.eq_eff_1.str.replace(",", "."),
            eq_fin_1=lambda df_: df_.eq_fin_1.str.replace(",", "."),
            eq_liq_1=lambda df_: df_.eq_liq_1.str.replace(",", "."),
            eq_pat_1=lambda df_: df_.eq_pat_1.str.replace(",", "."),
            # Date
            date_iscr=lambda df_: pd.to_datetime(
                df_.date_iscr, errors="coerce"
            ),
            date_init=lambda df_: pd.to_datetime(
                df_.date_init, errors="coerce"
            ),
            delta=lambda df_: months_diff(
                datetime.today(), pd.to_datetime(df_.date_init, errors="coerce")
            ),
        )

我将使用我的库 - convtools ,有Table助手(文档| github )允许将表格数据作为 stream 处理。

注意事项:

  1. 由于没有db.csv样本,我无法正确测试
  2. pd.read_csv支持decimal=','参数,所以最好使用它。 但我仍在复制您的代码行为,以便您可以在其他情况下使用它(例如,去除逗号 - 组分隔符)
  3. 下面的代码没有做任何on_bad_lines="skip"
from convtools import conversion as c
from convtools.contrib.tables import Table


float_cols = ["roe", "roi", "ros", "longitudine_dd", "latitudine_dd", "sfin", "cap_del", "cap_sott", "cap_vers", "eq_ec_1", "eq_eff_1", "eq_fin_1", "eq_liq_1", "eq_pat_1"]
date_cols = ["date_iscr", "date_init"]


def months_diff(a, b):
    return 12 * (a.year - b.year) + (a.month - b.month)


def parse_datetime(value, default):
    try:
        return datetime.strptime(value, "%Y-%m-%d")
    except (ValueError, TypeError):
        return default


rows_iter = (
    Table.from_csv(
        "db.csv", header=True, dialect=Table.csv_dialect(delimiter="\t")
    )
    .filter(
        c.and_(
            c.col("piva").is_not(None),
            c.col("code").is_not(None),
            c.col("provincia_cd").pipe(len) == 2,
            c("\.").not_in(c.col("ateco")),
        )
    )
    .update(
        **{
            column: c.col(column).call_method("replace", ",", ".")
            for column in float_cols
        },
        **{
            column: c.call_func(parse_datetime, c.col(column), default=None)
            for column in date_cols
        },
    )
    .update(
        delta=c.col("date_init").and_then(
            c.call_func(months_diff, date.today(), c.this)
        )
    )
    .into_iter_rows(dict)
)

结果是一个可迭代的 dicts,您可以将其直接提供给pd.DataFramepolars (无论如何)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM