【问题标题】:Finding miminum values by columns for a pandas DataFrame containing NaN elements按列查找包含 NaN 元素的 pandas DataFrame 的最小值
【发布时间】:2019-01-20 11:33:51
【问题描述】:

我正在尝试获取两个 pandas Series 之间的最小值。碰巧该系列中的某些元素是NaN,当与数字进行比较时,我想得到NaN 的结果。

为什么我使用np.min函数

我使用了np.min 函数。这是因为我理解使用min 函数会导致错误,因为当列表中存在NaN 元素时,输出取决于列表中的顺序。

当我跑步时:

import numpy as np
print min([1,np.nan])
print min([np.nan,1])

我得到结果:

>>> 
1
nan

当我跑步时:

import numpy as np
print np.min([np.nan,1])
print np.min([1,np.nan])

我得到了我的期望:

>>> 
nan
nan

用于查找两个pandas 系列之间的最小值的玩具示例代码

考虑到以前的结果,我使用了np.minfunction。但是,如果我使用两个 Series 运行以下玩具示例代码,创建一个 DataFrame 并找到最小值,我会得到数字而不是 NaN,正如我在比较 NaN 和数字时所期望的那样。

import pandas as pd
import numpy as np
s1 = pd.Series([1,2,3,4,5])
s2 = pd.Series([np.nan, np.nan, np.nan, 0, np.nan])
df1 = pd.DataFrame([s1,s2])
df2 = pd.DataFrame([s2,s1])
r1 = np.min(df1,axis=0)
r2 = np.min(df2,axis=0)
print r1
print r2

这会导致以下打印结果:

>>> 
0    1.0
1    2.0
2    3.0
3    0.0
4    5.0
dtype: float64
0    1.0
1    2.0
2    3.0
3    0.0
4    5.0
dtype: float64

但我希望结果与Serie s2 相同,即DataFrame df1

>>> df1
     0    1    2    3    4
0  1.0  2.0  3.0  4.0  5.0
1  NaN  NaN  NaN  0.0  NaN

问题

在为我用两个系列创建的DataFrame 查找最小值时,是否有我遗漏的函数或者我做错了什么?我希望 NaN 成为比较数字和 NaN 元素时的结果...

注意:我将python 2.7numpy 1.13.3pandas 0.22.0一起使用

【问题讨论】:

  • 我不确定我是否理解.. 在比较 any 数字时,您希望始终返回 NaN
  • 正确@RafaelC

标签: python pandas numpy dataframe nan


【解决方案1】:

IIUC,这是np.minimum的定义

比较两个数组并返回一个包含元素的新数组 最小值。 如果要比较的元素之一是 NaN,那么 返回元素。 如果两个元素都是 NaN,那么第一个是 返回。

r1 = np.minimum(df1.loc[0, :], df1.loc[1, :])
r2 = np.minimum(df2.loc[0,:], df2.loc[1, :])

【讨论】:

  • 介意解释否决票吗?也许我误解了这个问题,如果downvoter能解释一下会很高兴;)
  • 我也很好奇,这似乎是一个很好的选择,可以导致 OP 的所需输出。 (已经+1)(注意,我也被否决了,我猜我们都没有解释为什么会发生这种情况)
  • 不知道为什么有人在这里投反对票。似乎还对另一个有用的问题投了反对票。
  • 您能解释一下为什么np.minimum(np.asarray(s1),np.asarray(s2)) 会导致array([ 1., 2., 3., 0., 5.]) 改为吗?
  • @sacul 这可能是有道理的,但我认为这里没有什么要解释的,因为该函数专门设计为在发生这种情况时返回 NaN。它已经从源代码这样编程(我想这应该是足够的解释哈哈)
【解决方案2】:

IIUC,您可以将系列的values 作为np.array 传递给np.min,您会得到np.min 所期望的行为:

>>> np.min(df2.values,axis=0)
array([nan, nan, nan,  0., nan])
>>> np.min(df1.values,axis=0)
array([nan, nan, nan,  0., nan])

您还可以将参数skipna=False 应用于pands.DataFrame.min,同时考虑NaN 值:

>>> df1.min(axis=0, skipna=False)
0    NaN
1    NaN
2    NaN
3    0.0
4    NaN
dtype: float64
>>> df2.min(axis=0, skipna=False)
0    NaN
1    NaN
2    NaN
3    0.0
4    NaN
dtype: float64

【讨论】:

  • 是的,我也注意到了这一点。但是您能评论一下为什么会出现这种情况吗? np.min docs (help(np.min)) 建议始终传播 NaN 值。
  • 我喜欢使用df1.min(skipna=False) 的可能性,这更能描述我正在做的事情,它会产生我想要的结果。我仍然不知道为什么需要对 DataFrames 使用 values 选项以使 np.min 按预期工作...
猜你喜欢
  • 2017-11-02
  • 1970-01-01
  • 2017-12-31
  • 2018-07-26
  • 1970-01-01
  • 1970-01-01
  • 2017-04-30
  • 2016-08-29
  • 1970-01-01
相关资源
最近更新 更多