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

Cle*_*leb 5 python replace missing-data pandas

这个问题是由我刚才给出的答案推动的.

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

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
Run Code Online (Sandbox Code Playgroud)

而且我想用NaN行的最大值替换,我能做到

df.apply(lambda row: row.fillna(row.max()), axis=1)
Run Code Online (Sandbox Code Playgroud)

这给了我想要的输出

      a     b     c
0   1.0   3.0   3.0
1   2.0   5.0   5.0
2  34.0  10.0  34.0
Run Code Online (Sandbox Code Playgroud)

但是,当我使用时

df.apply(lambda row: row.fillna(max(row)), axis=1)
Run Code Online (Sandbox Code Playgroud)

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

     a     b     c
0  1.0   3.0   3.0
1  2.0   5.0   5.0
2  NaN  10.0  34.0
Run Code Online (Sandbox Code Playgroud)

的确,如果我手工检查

max(df.iloc[0, :])
max(df.iloc[1, :])
max(df.iloc[2, :])
Run Code Online (Sandbox Code Playgroud)

然后它打印

3.0
5.0
nan
Run Code Online (Sandbox Code Playgroud)

做的时候

df.iloc[0, :].max()
df.iloc[1, :].max()
df.iloc[2, :].max()
Run Code Online (Sandbox Code Playgroud)

它打印出预期的

3.0
5.0
34.0
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么max()在三个案例中的一个案例中失败但在所有案例中都没有.为什么NaN有时会被忽略而有时不被忽

Bre*_*arn 16

原因是max通过将第一个值作为"到目前为止看到的最大值"进行工作,然后检查每个其他值以查看它是否大于目前为止看到的最大值.但是nan被定义为与它的比较总是返回False ---也nan > 1就是假,但1 > nan也是假的.

因此,如果您从nan数组中的第一个值开始,则每个后续比较都将检查是否some_other_value > nan.这将始终是错误的,因此nan将保持其"迄今为止最大可见"的位置.另一方面,如果nan不是第一个值,那么当达到它时,比较nan > max_so_far将再次为假.但在这种情况下,这意味着当前"迄今为止看到的最大值"(不是nan)将保持迄今为止的最大值,因此将始终丢弃nan.


Jam*_*eld 6

在第一种情况下,您正在使用numpy max函数,它知道如何处理numpy.nan.

在第二种情况下,您正在使用maxpython中的内置函数.这不知道如何处理numpy.nan.据推测,这种效应是由于numpy.nan浮点数的任何比较(>,<,==等)导致False.一种显而易见的实现max方法是迭代迭代(在这种情况下为行)并检查每个值是否大于前一个值,如果是,则将其存储为最大值.因为当比较值之一时,大于比较的值总是为假numpy.nan,所记录的最大值是否是您想要的数量或numpy.nan完全取决于第一个值是否numpy.nan.