
嗨我是花姐,老读我文章的都知道,我自己平时写策略、做数据清洗,Pandas 几乎是天天用。
咱们可能都学过 Pandas 的基础,但你知道吗?其实有不少小技巧,能让你干活快好几倍! 今天,我给你挑了 20 个特别实用的 Pandas 操作,不夸张,学会它们真的能帮你省出好几个小时,让你处理数据效率翻倍。 想知道都有哪些?那就跟着我一起往下看吧!
1. 只读取你真正需要的列
你是不是经常这样?
python
df = pd.read_csv("big.csv")
然后读个几百 MB 的 CSV,机器就开始嗡嗡响,人也开始烦躁......
其实你只需要它的几列,干嘛读全部?
更聪明的做法是:
python
df = pd.read_csv("big.csv", usecols=["id", "total", "date"], dtype_backend="pyarrow")
咋回事?
usecols
直接告诉 Pandas:别废话,就给我这三列。省事!dtype_backend="pyarrow"
是个新东西,Pandas 2.0 后才有,用的是 Apache Arrow 的数据结构,速度快,内存占用也低。
适合啥场景?
像我做因子研究时,一份数据 1000 万行,但我可能只看其中 2 列。这时候这一招就太香了
2. 自动优化列类型,降低内存使用率
读完 CSV 之后你有没发现,明明整列是整数,Pandas 偏给你识别成 float64,还有一堆 object 类型,看着都头疼。
不改会咋样?
不仅占内存,而且后续 .groupby()
、.merge()
都会拖慢速度,关键有时候还会出 bug......
聪明的你应该这样做:
python
df = df.convert_dtypes(dtype_backend="pyarrow")
它干了啥?
- 自动帮你找出最合适的数据类型,比如 Int64、string 而不是 object
- Arrow 格式的字符串操作快得飞起(你
.str.contains()
跑过你就懂了)
用我自己的项目举个例子:我之前处理一个上市公司年报表格,改用这个方法后,内存占用直接降了快一半。省得我电脑一跑就卡死
3. 一行搞定全表概况
你是不是也这么干过:
python
df.info()
df.describe()
df['某列'].value_counts()
是不是写得你手疼眼花?
有更快的办法👇:
python
df.describe(include="all", datetime_is_numeric=True)
这个指令真的有点牛:
include="all"
:所有类型的列都分析,包括文本和时间datetime_is_numeric=True
:把时间当成数字,能看到最大、最小、平均时间
你可能在想:这有啥特别的?其实它可以帮你秒发现很多问题,比如:
- 某列本该唯一,结果发现 unique 有 3 万?
- 某个时间列平均值是 1970?是不是数据错了?
4. 精准知道内存吃了多少
你电脑要是经常爆内存,那你一定要会这个操作:
python
df.memory_usage(deep=True).sum() / 1048576
除以1048572(1024^2)是把字节转换成MB ,可以直接告诉你 DataFrame 实际用了多少 MB。
注意 deep=True
是关键,它会把 object 类型(比如 string)真正占用的空间算进去,不然你看到的只是个"假数字"。
有时候跑着跑着代码突然爆了个 MemoryError,我整个人都不好了...... 这时候就得看看到底是哪列吃内存吃得这么猛; 用这招还能帮你调优 Dask 或 Modin 的分布式任务,效果杠杠的。
5. 用 SQL 一样的语法筛选数据
有些朋友可能不习惯 Pandas 的 df[df.col == x]
这种写法,总觉得又长又绕。
你可以换种方式写得更清楚👇:
python
high_apac = df.query("sales > 1000 & region == 'APAC'")
就像在写 SQL 一样。
为什么强?
- 支持动态字符串,适合做前端交互
- 内部用的是
numexpr
引擎,计算快 - 写起来干净,读起来顺溜(尤其多条件时)
6. 只取 Top N,不用全排序
你还在用这种方式取前十吗?
python
df.sort_values("profit", ascending=False).head(10)
这可是把整张表都排完了!浪费!
有个更高效的写法:
python
top10 = df.nlargest(10, "profit")
这操作底层用的是快速选择算法,只排出前N大的行,速度更快,尤其数据量大的时候差距特别明显。
7. 列之间的运算写得更优雅
一般我们写这样:
python
df["revenue"] = df["quantity"] * df["price"]
很正常对吧?但如果你操作复杂点,变量多,很容易乱套。
不如这样:
python
df["revenue"] = df.eval("quantity * price")
支持字符串表达式,而且底层走的是 Pandas 内部的表达式计算引擎,比你手动算更快更省内存。
而且对链式操作特别友好,不用中途取值赋值再返回,非常干净。
8. 用 assign()
给 DataFrame 添加列(还能链式)
想新增一列,不想打断链式调用,写得优雅点?
用这个:
python
df = df.assign(gm=lambda x: x.gross - x.cogs)
不影响原 DataFrame,还可以连着继续 .groupby()
、.plot()
各种方法链。
我写 pipeline 时几乎必用这个,有种"写函数式"的爽感
9. 计算组内占比(比如每类产品销量占比)
你有没有被 .groupby().sum()
+ .merge()
弄得晕头转向?
其实只需要一行:
python
df["sales_share"] = df.groupby("product")["sales"].transform(lambda x: x / x.sum())
一行解决组内占比问题,还能原地加回每行数据。真的是又短又强。
10. 多指标汇总(指定列+函数)
不想再被下面这种写法绑架了:
python
df.groupby("region")["sales"].agg(["sum", "mean"])
多层索引真不太友好......
这样写:
python
summary = df.groupby("region", as_index=False).agg(
total=("sales", "sum"), margin_avg=("margin", "mean")
)
直接命名每一列,结果 DataFrame 就能直接拿来拼图表或者写报告,很干净。
11. 宽表变长表,画图/建模更方便
你做可视化时,是不是经常提示"long format required"?
一招搞定:
python
long = df.melt(id_vars="id", var_name="metric", value_name="value")
比如原来列是 jan_sales, feb_sales
,现在就成了:
id | metric | value |
---|---|---|
1 | jan_sales | 100 |
1 | feb_sales | 120 |
画图神器 seaborn 最喜欢这种格式,妥妥的打工效率利器
12. 列里嵌了个列表?一行展开!
有时你会遇到这种:
python
df["tags"] = [["A", "B"], ["A"], ["C", "D", "E"]]
用 .explode()
简直是神器:
python
flat = df.explode("tags")
每个 list 元素都会变成一行,其他列自动复制,超方便!
不用 .apply()
+ pd.Series
那种啰嗦操作,炸裂
13. 做交叉表,还能补0?
想看每天每个区域卖了多少?
一行搞定:
python
pivot = df.pivot_table(index="date", columns="region", values="sales", aggfunc="sum", fill_value=0)
这操作结合了 groupby + unstack + fillna
的功能,直接给你输出热力图用的表格💥
14. 一行干掉缺得太多的列
是不是经常写:
python
for col in df.columns:
if df[col].isna().mean() > 0.2:
df.drop(col, axis=1, inplace=True)
其实这一行就够了:
python
df = df.dropna(axis=1, thresh=len(df) * 0.8)
保留非空比例超过 80% 的列,其他的直接扔掉。
做数据清洗的第一步,我基本上都是靠它。
15. 处理时间列+时区,一步到位
想把字符串转时间,还要加时区?
用这个:
python
df["date"] = pd.to_datetime(df.date).dt.tz_localize("UTC").dt.tz_convert("Asia/Shanghai")
对全球交易数据、跨国日志特别重要。不然你比较时间的时候,很可能错几小时到几天,坑得很
16. 一行验证邮箱格式(用正则)
说出来你可能不信,我见过有数据里 email 是"[email protected]"。
这都能进数据库?离谱
一行检测出异常邮箱:
python
df["email_ok"] = df.email.str.contains(r"^[\w\.-]+@[\w\.-]+\.\w+$", na=False)
用正则搞定,而且是矢量化操作 ,比 apply()
快非常多!
17. 补齐时间序列的缺失日期
如果你在做预测模型,时间断层可能直接让模型崩掉。
这样写
python
daily = df.set_index("timestamp").asfreq("D").ffill()
一天一行,缺的就用前一个值补上。不用你自己生成时间序列再 merge
,又麻烦又慢。
18. 一行搞定同比增长
同比计算老写错?别算错公式了兄弟:
python
df["yoy"] = df["sales"].pct_change(12).mul(100).round(2)
算出来就是同比百分比,已经帮你处理了除以0的问题。
我写季度、年度报表时,每次都靠这句。
19. 开启 Copy-on-Write 模式,省内存大招
你可能经常会这样操作:
python
df1 = df[df["a"] > 0]
df1["b"] = df1["c"] * 2
你以为改的是 df1
,结果 df
也被影响了......
解决方式:
python
pd.options.mode.copy_on_write = True
Pandas 2.0 的新功能,写入时才复制,平时共享内存。速度更快、代码更安全。
20. 用 .style
快速看异常值
做 EDA 想看看哪些值特别大特别小?不想写图?这就来:
python
df.style.background_gradient()
自动加上颜色梯度,直接在 Jupyter Notebook 看效果。
你一眼就能看出"哪里不对劲",尤其是有极端值时,一看就知道谁"搞事"了
最后唠几句:
聪明的你,肯定已经意识到:这些小技巧,其实能帮你在项目里少写几十行代码,而且更高效、更优雅、更不容易出错。
别小看这些"语法糖",它们真的是工作中救命的工具。
希望你能挑几招带回去,立马实践一下。用在你自己日常的数据处理里,感受一下那种"嗯?怎么这么顺手?"的感觉