【问题标题】:Python Pandas - difference between 'loc' and 'where'?Python Pandas - “loc”和“where”之间的区别?
【发布时间】:2019-07-20 21:27:45
【问题描述】:

只是好奇 'where' 的行为以及为什么要在 'loc' 上使用它。

如果我创建一个数据框:

df = pd.DataFrame({'ID':[1,2,3,4,5,6,7,8,9,10], 
                   'Run Distance':[234,35,77,787,243,5435,775,123,355,123],
                   'Goals':[12,23,56,7,8,0,4,2,1,34],
                   'Gender':['m','m','m','f','f','m','f','m','f','m']})

然后应用'where'函数:

df2 = df.where(df['Goals']>10)

我得到以下过滤掉Goals> 10的结果,但将其他所有内容保留为NaN:

  Gender  Goals    ID  Run Distance                                                                                                                                                  
0      m   12.0   1.0         234.0                                                                                                                                                  
1      m   23.0   2.0          35.0                                                                                                                                                  
2      m   56.0   3.0          77.0                                                                                                                                                  
3    NaN    NaN   NaN           NaN                                                                                                                                                  
4    NaN    NaN   NaN           NaN                                                                                                                                                  
5    NaN    NaN   NaN           NaN                                                                                                                                                  
6    NaN    NaN   NaN           NaN                                                                                                                                                  
7    NaN    NaN   NaN           NaN                                                                                                                                                  
8    NaN    NaN   NaN           NaN                                                                                                                                                  
9      m   34.0  10.0         123.0  

如果我使用'loc'函数:

df2 = df.loc[df['Goals']>10]

它返回没有 NaN 值的子集数据帧:

  Gender  Goals  ID  Run Distance                                                                                                                                                    
0      m     12   1           234                                                                                                                                                    
1      m     23   2            35                                                                                                                                                    
2      m     56   3            77                                                                                                                                                    
9      m     34  10           123 

所以基本上我很好奇为什么你会使用 'where' 而不是 'loc/iloc' 以及为什么它返回 NaN 值?

【问题讨论】:

  • 相关:Pandas mask / where methods versus NumPy np.where。总结:Pandas where 很少能胜过(或可读性更强)更流行的 NumPy np.where,因此前者通常无关紧要。
  • 谢谢jpp。您提出的有趣问题和“ead”的回答。我会看看 numpy 是否使用 'where'。

标签: python pandas


【解决方案1】:

loc 视为过滤器 - 只给我符合条件的 df 部分。

where 最初来自 numpy。它遍历一个数组并检查每个元素是否符合条件。因此,它会返回整个数组,并返回结果或NaNwhere 的一个不错的功能是您还可以取回不同的东西,例如df2 = df.where(df['Goals']>10, other='0'),将不满足条件的值替换为0。

ID  Run Distance Goals Gender
0   1   234      12     m
1   2   35       23     m
2   3   77       56     m
3   0   0        0      0
4   0   0        0      0
5   0   0        0      0
6   0   0        0      0
7   0   0        0      0
8   0   0        0      0
9   10  123      34     m

另外,where 仅用于条件过滤,loc 是 Pandas 中的标准选择方式,iloc 也是如此。 loc 使用行名和列名,而iloc 使用它们的索引号。所以对于loc,你可以选择返回,比如df.loc[0:1, ['Gender', 'Goals']]

    Gender  Goals
0   m   12
1   m   23

【讨论】:

  • 这非常有帮助,谢谢。所以 'loc' 过滤器和 'where' 更多地用于您想要将不符合条件的值更改为其他值的位置。完美,谢谢!
【解决方案2】:

如果检查文档DataFrame.where,它将按条件替换行 - 默认为 NAN,但可以指定值:

df2 = df.where(df['Goals']>10)
print (df2)
     ID  Run Distance  Goals Gender
0   1.0         234.0   12.0      m
1   2.0          35.0   23.0      m
2   3.0          77.0   56.0      m
3   NaN           NaN    NaN    NaN
4   NaN           NaN    NaN    NaN
5   NaN           NaN    NaN    NaN
6   NaN           NaN    NaN    NaN
7   NaN           NaN    NaN    NaN
8   NaN           NaN    NaN    NaN
9  10.0         123.0   34.0      m

df2 = df.where(df['Goals']>10, 100)
print (df2)
    ID  Run Distance  Goals Gender
0    1           234     12      m
1    2            35     23      m
2    3            77     56      m
3  100           100    100    100
4  100           100    100    100
5  100           100    100    100
6  100           100    100    100
7  100           100    100    100
8  100           100    100    100
9   10           123     34      m

另一种语法称为boolean indexing,用于过滤行 - 删除匹配条件的行。

df2 = df.loc[df['Goals']>10]
#alternative
df2 = df[df['Goals']>10]

print (df2)
   ID  Run Distance  Goals Gender
0   1           234     12      m
1   2            35     23      m
2   3            77     56      m
9  10           123     34      m

如果可以使用loc,还可以按条件按行过滤,按名称按列过滤:

s = df.loc[df['Goals']>10, 'ID']
print (s)
0     1
1     2
2     3
9    10
Name: ID, dtype: int64

df2 = df.loc[df['Goals']>10, ['ID','Gender']]
print (df2)
   ID Gender
0   1      m
1   2      m
2   3      m
9  10      m

【讨论】:

  • 这很有意义,非常感谢。还要感谢您提供有关替代方案的提示!
【解决方案3】:
  • loc 只检索符合条件的行。
  • where 返回整个数据框,替换不符合条件的行(默认为 NaN)。

【讨论】:

  • 太好了,谢谢。 “在哪里”比最初想象的要有用得多!
猜你喜欢
  • 2020-02-17
  • 2018-02-24
  • 2023-04-08
  • 1970-01-01
  • 2011-09-09
  • 1970-01-01
  • 2017-10-07
  • 2013-11-25
  • 1970-01-01
相关资源
最近更新 更多