[英]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.