数据STUDIO

解锁Pandas10个查询方法,让数据处理效率翻倍

Image

Image
 告别繁琐循环,拥抱高效数据分析

如果你曾经在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 -设为星标,干货速递ImageImage