这个问题是由我前一段时间提出的an answer推动的。
我们说我有一个像这样的数据框
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
替换为行的最大值I can do
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()
在三个案例中的一个案例中失败但在所有案例中都没有。为什么NaN
有时会被忽略而有时不会被忽略?
答案 0 :(得分:9)
原因是max
的工作原理是将第一个值作为“到目前为止看到的最大值”,然后检查每个其他值以查看它是否大于目前为止看到的最大值。但nan
已定义,因此与它的比较始终返回False - 即nan > 1
为false,但1 > nan
也为false。
因此,如果您从nan
开始作为数组中的第一个值,则每次后续比较都将检查some_other_value > nan
。这将永远是错误的,因此nan
将保持其“迄今为止看到的最大值”的位置。另一方面,如果nan
不是第一个值,那么当达到时,比较nan > max_so_far
将再次为假。但在这种情况下,这意味着当前“迄今为止看到的最大值”(不是nan
)将保持迄今为止的最大值,因此将永远丢弃nan。
答案 1 :(得分:6)
在第一种情况下,您正在使用numpy max
函数,该函数知道如何处理numpy.nan
。
在第二种情况下,您正在使用python中的内置max
函数。这不知道如何处理numpy.nan
。据推测,这种效应是由于numpy.nan
与浮点数的任何比较(>,<,==等)导致False。实现max
的一种显而易见的方法是迭代迭代(在这种情况下为行)并检查每个值是否大于前一个值,并将其存储为最大值(如果是这样)。由于当比较值之一为numpy.nan
时,大于比较的值始终为假,因此记录的最大值是否为您想要的数字或numpy.nan
完全取决于第一个值是否为numpy.nan
或不。
答案 2 :(得分:1)
这是由于列表中元素的排序。首先,如果你输入
max([1, 2, np.nan])
结果为2
,而
max([np.nan, 2, 3])
给出np.nan
。这样做的原因是max
函数逐个遍历列表中的值,并进行比较,如下所示:
if a > b
现在,如果我们看一下与nan
比较时得到的结果,np.nan > 2
和1 > np.nan
都会给False
,所以在一种情况下,运行的最大值会替换为nan
而另一方则不是。
答案 3 :(得分:0)
两者不同:max()vs df.max()。
max():python内置函数,它必须是非空的可迭代。点击这里: https://docs.python.org/2/library/functions.html#max
当pandas dataframe - df.max(skipna = ..)时,有一个名为skipna的参数,默认值为True,这意味着排除了NA / null值。点击这里: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.max.html