一尘不染

为什么max()有时返回nan而有时忽略它?

python

假设我有一个这样的数据框

import numpy as np
import pandas as pd

df = pd.DataFrame({'a': [1, 2, np.nan], 'b': [3, np.nan, 10], 'c':[np.nan, 5, 34]})

     a     b     c
0  1.0   3.0   NaN
1  2.0   NaN   5.0
2  NaN  10.0  34.0

我想,以取代NaN由最大行的,我可以做

df.apply(lambda row: row.fillna(row.max()), axis=1)

这给了我想要的输出

      a     b     c
0   1.0   3.0   3.0
1   2.0   5.0   5.0
2  34.0  10.0  34.0

但是,当我使用

df.apply(lambda row: row.fillna(max(row)), axis=1)

由于某种原因,仅在以下三种情况中的两种情况下才可以正确更换它:

     a     b     c
0  1.0   3.0   3.0
1  2.0   5.0   5.0
2  NaN  10.0  34.0

确实,如果我亲自检查

max(df.iloc[0, :])
max(df.iloc[1, :])
max(df.iloc[2, :])

然后打印

3.0
5.0
nan

做的时候

df.iloc[0, :].max()
df.iloc[1, :].max()
df.iloc[2, :].max()

它打印预期的

3.0
5.0
34.0

我的问题是,为什么max()在三种情况中有一种失败了,但在全部3种情况中都没有失败NaN


阅读 242

收藏
2021-01-20

共1个答案

一尘不染

原因是max通过将第一个值作为“到目前为止看到的最大值”,然后互相检查该值是否大于迄今为止看到的最大值来起作用。但是nan,定义它是为了使与它的比较始终返回False
nan > 1即为false但1 > nan也为false。

因此,如果您以nan数组中的第一个值开头,则每个后续比较都将检查是否为some_other_value > nan。这将始终是错误的,因此nan将保留其位置为“到目前为止所能看到的最大值”。另一方面,如果nan不是第一个值,那么当达到第一个值时,比较`nan

max_so_far将再次为假。但是在这种情况下,这意味着当前的“到目前为止看到的最大值”(不是nan`)将保持到目前为止看到的最大值,因此nan将始终被丢弃。

2021-01-20