解锁Pandas10个查询方法,让数据处理效率翻倍
告别繁琐循环,拥抱高效数据分析
如果你曾经在Pandas中编写无尽循环、冗长条件判断或笨拙的过滤器,那么你并不孤单。Pandas功能强大,但有时似乎需要大量代码才能实现想要的功能。
好消息是:Pandas有一系列查询方法和快捷方式,能将十几行代码压缩到一两行。多年来,我收集了这些宝贵技巧,它们 consistently 为我节省了大量的调试和数据整理时间。
今天,云朵君和大家一起深入探讨10个Pandas查询方法,它们将改变你过滤、切片和探索数据的方式。
1. .query():类似SQL的过滤方式
无需再写:
df[df['age'] > 30]
只需:
df.query('age > 30')
代码更清晰、更易读。在处理多个条件时尤其方便:
df.query('age > 30 & city == "London"')
这感觉就像在Pandas中写SQL。
2. .isin():成员资格检查
告别难看的OR条件。
df[df['city'].isin(['London', 'Paris', 'Tokyo'])]
代替:
df[(df['city'] == 'London') | (df['city'] == 'Paris') | (df['city'] == 'Tokyo')]
这是分类过滤的完美快捷方式。
3. .between():范围查询
检查数值范围变得毫不费力:
df[df['salary'].between(50000, 100000)]
远比以下方式简单:
df[(df['salary'] >= 50000) & (df['salary'] <= 100000)]
可以将其视为Pandas中SQL的BETWEEN等价物。
4. .str.contains():文本过滤
需要基于文本模式过滤行?
df[df['job_title'].str.contains('engineer', case=False)]
它支持正则表达式,可以不区分大小写,而且比写循环快得多。
5. .loc与布尔掩码结合使用
有时你想一次性完成过滤和赋值:
df.loc[df['age'] < 18, 'status'] = 'minor'
与逐行应用函数相比,这能节省大量时间。
6. .iloc:基于位置的查询
当你只需要前10行或第5列时:
df.iloc[:10, 2]
这是基于零索引的,速度快,在处理索引而非标签时通常更直观。
7. .nlargest()和.nsmallest()
当你只需要最大值或最小值时,无需排序整个DataFrame:
df.nlargest(5, 'salary')
df.nsmallest(5, 'salary')
一行代码替代排序+切片。
8. .where():条件过滤
无需分多步替换值:
df['adjusted_salary'] = df['salary'].where(df['salary'] > 50000, 50000)
这将保持高于5万的薪资不变,但将所有其他值提高至5万。这就像是内置在Pandas中的IF语句。
9. .mask():where()的反向操作
where()的反义词,适用于条件替换:
df['discounted'] = df['price'].mask(df['price'] > 100, 100)
意思是:"如果条件为真,则将这些值替换为其他值"。
10. .eval():表达式查询
当性能很重要时,.eval()非常出色。
df.eval('total = price * quantity')
它的速度更快,因为Pandas在内部解析表达式,并且保持代码简短易读。
查询方法在Pandas中的架构流程
以下是在实际管道中查询方法如何协同工作的流程:
原始DataFrame
|
v
+--------------------+
| 基础过滤 | -> query(), isin(), between()
+--------------------+
|
v
+--------------------+
| 字符串/正则操作 | -> str.contains()
+--------------------+
|
v
+--------------------+
| 条件逻辑 | -> where(), mask(), eval()
+--------------------+
|
v
+--------------------+
| 排名查询 | -> nlargest(), nsmallest()
+--------------------+
|
v
清洗和查询后的数据
通过将方法链接成可重复、人类可读的管道,这种流程可以节省时间。
更多提升效率的Pandas技巧
除了上述查询方法,还有一些可以进一步提升数据处理效率的技巧:
使用正确数据类型
读取数据时指定数据类型可以显著提升性能和减少内存使用:
dtypes = {'id': 'int32', 'price': 'float32', 'category': 'category'}
df = pd.read_csv('data.csv', dtype=dtypes)
向量化操作
避免使用循环,而是使用Pandas的向量化操作:
# 反面例子 (慢)
for i in range(len(df)):
df.loc[i, 'score'] = df.loc[i, 'points'] * 0.8
# 正面例子 (快)
df['score'] = df['points'] * 0.8
使用DuckDB处理Pandas DataFrame
对于复杂查询,可以使用DuckDB直接在Pandas DataFrames上运行SQL:
import duckdb
result = duckdb.query("SELECT sum(a) FROM mydf WHERE b > 10").to_df()
实际应用案例
让我们看一个实际例子,结合多种查询方法:
假设我们有一个销售数据集,想要找出伦敦地区销量前5的产品,且销量在100到1000之间,同时**产品名称包含"旗舰"**:
# 传统方法(冗长)
london_sales = df[df['city'] == 'London']
filtered_sales = london_sales[(london_sales['sales'] >= 100) & (london_sales['sales'] <= 1000)]
flagship_products = filtered_sales[filtered_sales['product_name'].str.contains('旗舰')]
result = flagship_products.sort_values('sales', ascending=False).head(5)
# 使用查询方法(简洁高效)
result = (
df.query('city == "London"')
.query('sales.between(100, 1000)')
.loc[df['product_name'].str.contains('旗舰')]
.nlargest(5, 'sales')
)
为什么这些查询方法很重要
说实话:数据分析不是为了编写聪明的代码——而是为了更快地获取洞察。
.query()感觉像SQL,为分析师架起了桥梁.isin()和.between()消除了冗长的条件判断.nlargest()和.nsmallest()跳过了不必要的排序开销.eval()在处理大型数据集时提升了性能
回报是什么?你编写更少的代码,犯更少的错误,长期来看节省了大量时间。
写在最后
Pandas的优点是协助开发人员高效处理问题——那种不想在能一行代码解决问题时写10行代码的人。这些查询方法并不是晦涩的技巧;它们是非常有用的生产力利器。
下次当你在混乱的数据中埋头苦干时,请记住:Pandas已经内置了快捷方式。你只需要使用它们。
你最常用哪个查询方法?欢迎在评论区分享——关注我们以获取更多Pandas和Python生产力技巧!
🏴☠️宝藏级🏴☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉Python|MySQL|数据分析|数据可视化|机器学习与数据挖掘|爬虫等,从入门到进阶!
长按👇关注- 数据STUDIO -设为星标,干货速递