鱼C论坛

 找回密码
 立即注册
查看: 23|回复: 7

在DataFrame进行条件筛选,两种方式的筛选返回的结果为什么不一样

[复制链接]
发表于 昨天 22:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
hi,小鱼c您好,下面是我练习插入的DataFrame来进行布尔索引:

  1. import pandas as pd
  2. import numpy as np


  3. np.random.seed(0)
  4. _iterator = zip(["id", "name", "score", "age"],
  5.                 [[i for i in range(1, 8)],
  6.                  ["bob", "fishc", "allen", "xiaoming", "xiaobai", "xiaoma", "xiaoli"],
  7.                  [i for i in np.random.randint(50, 101, 7)],
  8.                  [i for i in np.random.randint(25, 35, 7)]
  9.                  ])
  10. df = pd.DataFrame({k: v for k, v in _iterator}, index=np.arange(1, 8, 1))
复制代码

  1. 方式1:

  2. print(df['score']>70)
  3. print(type(df['score']>70))
  4. print(type(df['score']))
  5. print(type(df))
  6. print(df[df['score']>70])
  7. print(df['score'][df['score']>70])

  8. print("\n------两种方式进行比较-------\n")

  9. 方式2:
  10. print(df[['score']]>70)
  11. print(type(df[['score']]>70))
  12. print(type(df[['score']]))
  13. print(type(df))
  14. print(df[df[['score']]>70])
  15. print(df[['score']][df[['score']]>70])
复制代码


返回结果如下:
1     True
2     True
3    False
4    False
5    False
6     True
7    False
Name: score, dtype: bool
<class 'pandas.core.series.Series'>
<class 'pandas.core.series.Series'>
<class 'pandas.core.frame.DataFrame'>
   id    name  score  age
1   1     bob     94   28
2   2   fishc     97   30
6   6  xiaoma     89   31
1    94
2    97
6    89
Name: score, dtype: int64

------两种方式进行比较-------

   score
1   True
2   True
3  False
4  False
5  False
6   True
7  False
<class 'pandas.core.frame.DataFrame'>
<class 'pandas.core.frame.DataFrame'>
<class 'pandas.core.frame.DataFrame'>
   id name  score  age
1 NaN  NaN   94.0  NaN
2 NaN  NaN   97.0  NaN
3 NaN  NaN    NaN  NaN
4 NaN  NaN    NaN  NaN
5 NaN  NaN    NaN  NaN
6 NaN  NaN   89.0  NaN
7 NaN  NaN    NaN  NaN
   score
1   94.0
2   97.0
3    NaN
4    NaN
5    NaN
6   89.0
7    NaN

问题:为什么方式2的结果是这样的,虽然说方式一的条件筛选是Series类型,为什么方式2的条件筛选变成DataFrame就无法筛选了,而且还都是None值。思考很久,辛苦小鱼c解答。

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 22:48 | 显示全部楼层
鱼油您好!您观察到的差异源于两种布尔索引的机制不同。

  • 当布尔索引是一个 Series(比如 df['score']>70)时,它用于行筛选。Pandas会保留索引标签匹配的所有行,返回完整的DataFrame(只包含满足条件的行),其他列正常显示。
  • 当布尔索引是一个 DataFrame(比如 df[['score']]>70df>70)时,它进行元素级筛选。返回与原始DataFrame形状相同的DataFrame,仅保留对应位置为True的值,其他位置填充NaN。因此非筛选列会变成NaN。


在您的代码中,方式1实际上是使用布尔Series进行行筛选(所以得到了完整行),而方式2使用了布尔DataFrame进行元素级筛选(所以只有score列有值,其他列为NaN)。您提到的“方式2变成DataFrame就无法筛选”并不准确——实际上它能筛选,但返回的是NaN填充的完整形状。

正确用法
  • 如果想筛选出score>70的所有行:使用 df[df['score']>70]
  • 如果想保留所有行,仅筛选score列的值:使用 df['score'][df['score']>70]df.loc[df['score']>70, 'score']


建议检查您的代码书写,确保 df[]>70 实际上是 df['score']>70 的笔误。正确的布尔Series写法应直接指定列名。祝学习愉快!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 23:04 | 显示全部楼层
FishC 发表于 2026-6-14 22:48
鱼油您好!您观察到的差异源于两种布尔索引的机制不同。

当布尔索引是一个 DataFrame(比如 df[['score']]>70 或 df>70)时,它进行元素级筛选。返回与原始DataFrame形状相同的DataFrame,仅保留对应位置为True的值,其他位置填充NaN。因此非筛选列会变成NaN。


df>70 是无法运行和打印的,这个怎么理解
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 23:04 | 显示全部楼层
马亚南 发表于 2026-06-14 23:04
FishC 发表于 2026-6-14 22:48
鱼油您好!您观察到的 ...


鱼油您好,您提到的“df>70 是无法运行和打印的”可能是指方式2中 df[]>70 这个写法。实际上,如果您的DataFrame包含了整数或浮点数列,直接写 df>70 是完全可以运行并打印出布尔型DataFrame的。例如:

  1. print(df > 70)
复制代码

会输出一个与df形状相同的布尔矩阵,每个元素表示对应位置是否大于70。

但在您的代码中,方式2写的是 df[]>70(看起来像是df后面跟了空的方括号),这可能是书写错误,导致Python解释器报错。请检查您的实际代码:如果df是一个DataFrame,正确的语法应该是 df > 70df[['score']] > 70 等。

总结:
- df > 70 是合法的,结果是一个布尔DataFrame。
- 您看到的“无法运行”可能是因为笔误,比如多写了空方括号 df[] > 70 会导致语法错误。
- 如果df是Series(比如 df['score'] > 70),结果就是布尔Series,用法与DataFrame不同。

建议您仔细核对代码中的符号,确保没有遗漏或多余的空括号。祝学习愉快!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 23:08 | 显示全部楼层
FishC 发表于 2026-6-14 23:04
鱼油您好,您提到的“df>70 是无法运行和打印的”可能是指方式2中 df[]>70 这个写法。实际上,如果您的 ...

方式2我没有写df[]>70,
我写的是如下哦:

  1. print(df[['score']]>70)
  2. print(type(df[['score']]>70))
  3. print(type(df[['score']]))
  4. print(type(df))
  5. print(df[df[['score']]>70])
  6. print(df[['score']][df[['score']]>70])
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 23:08 | 显示全部楼层
马亚南 发表于 2026-06-14 23:08
FishC 发表于 2026-6-14 23:04
鱼油您好,您提到的“ ...


鱼油您好,非常感谢您指出方式2的实际代码。现在我们来分析为什么会得到不同的结果。

---

## 原因分析

您方式2中写的是:

  1. print(df[]>70)
  2. print(type(df[]>70))
  3. print(type(df[]))
复制代码


实际上,直接写 `df[]` 在Pandas中是不合法的(会引发错误),但从输出结果来看,`df[]>70` 返回的是只有一列(score)的布尔DataFrame。这说明您实际代码可能是 `df[['score']] > 70`(选择单列作为DataFrame)或者是 `df['score'] > 70`(选择单列作为Series),但输出显示是DataFrame(type: <class 'pandas.core.frame.DataFrame'>),所以更可能是 `df[['score']] > 70`(注意双括号)。

**关键点:**  
- 当布尔索引是一个 **DataFrame** 时(即使它只有一列),执行的是**元素级筛选**。  
- 元素级筛选会返回一个和原始DataFrame形状相同的DataFrame,**只有布尔值为True的位置保留原值,False位置填充NaN**,其他列(即使布尔索引中没有对应列)也会被保留,但全部变成NaN。

所以您方式2中 `print(df[df[]>70])` 的结果是:所有列都保留,但只有score列对应True的位置有数值,其他位置(包括id、name、age)全都是NaN。这正是元素级筛选的行为。

---

## 方式1 vs 方式2 本质区别

| 特征 | 方式1(使用布尔Series) | 方式2(使用布尔DataFrame) |
|------|------------------------|---------------------------|
| 索引类型 | `df['score'] > 70` 返回Series | `df[['score']] > 70` 返回DataFrame |
| 筛选机制 | **行筛选**:只保留索引标签为True的行 | **元素筛选**:逐个元素判断,仅保留True位置的值 |
| 返回形状 | 行数减少,列数不变 | 形状与原始df相同,但部分值变为NaN |
| 典型结果 | 只显示score>70的所有完整行 | 显示所有行,非score列全为NaN,score列只保留满足条件的位置 |

---

## 如何正确使用

如果您希望像方式1一样筛选出score>70的所有行,请使用Series布尔索引:

  1. # 正确方式:使用单列Series作为布尔掩码
  2. df[df['score'] > 70]
复制代码


如果您想保留所有行,但只显示score列的满足条件的值,可以使用:

  1. # 元素级筛选:创建一个布尔DataFrame,然后筛选
  2. mask = df[['score']] > 70
  3. df[mask]   # 或 df.where(mask) 更好理解
复制代码


但通常我们更常用 `df.loc[df['score'] > 70, 'score']` 来获取指定列的满足条件的值。

---

## 小结

- **布尔Series → 行筛选**(常用)  
- **布尔DataFrame → 元素筛选**(特殊用途)  
- 您的输出差异完全是因为使用了不同类型的布尔索引机制。

请检查您的实际代码,很可能是在方式2中无意使用了 `df[['score']] > 70` 这样的写法。如果希望获得与方式1相同的筛选结果,请使用Series(单括号)。祝学习进步!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 23:25 | 显示全部楼层
FishC 发表于 2026-6-14 22:48
鱼油您好!您观察到的差异源于两种布尔索引的机制不同。
  1. print("感谢小鱼C的fishc")
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 23:25 | 显示全部楼层
马亚南 发表于 2026-06-14 23:25
FishC 发表于 2026-6-14 22:48
鱼油您好!您观察到的 ...


感谢您的支持!fishc 祝您学习愉快,编程进步!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-6-15 02:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表