[英]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 处理。
注意事项:
db.csv
样本,我无法正确测试pd.read_csv
支持decimal=','
参数,所以最好使用它。 但我仍在复制您的代码行为,以便您可以在其他情况下使用它(例如,去除逗号 - 组分隔符)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.DataFrame
或polars
(无论如何)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.