Pandas中位数的奇怪行为

wil*_*llk 17 python dataframe pandas

考虑以下数据帧:

       b           c     d     e  f     g     h
0   6.25  2018-04-01  True   NaN  7  54.0  64.0
1  32.50  2018-04-01  True   NaN  7  54.0  64.0
2  16.75  2018-04-01  True   NaN  7  54.0  64.0
3  29.25  2018-04-01  True   NaN  7  54.0  64.0
4  21.75  2018-04-01  True   NaN  7  54.0  64.0
5  21.75  2018-04-01  True  True  7  54.0  64.0
6   7.75  2018-04-01  True  True  7  54.0  64.0
7  23.25  2018-04-01  True  True  7  54.0  64.0
8  12.25  2018-04-01  True  True  7  54.0  64.0
9  30.50  2018-04-01  True   NaN  7  54.0  64.0
Run Code Online (Sandbox Code Playgroud)

(复制并粘贴并用于df = pd.read_clipboard()创建数据帧)

找到中位数最初没有问题:

df.median()

b    21.75
d     1.00
e     1.00
f     7.00
g    54.00
h    64.00
dtype: float64
Run Code Online (Sandbox Code Playgroud)

但是,如果删除列然后median找到列,则列的中位数将e消失:

new_df = df.drop(columns=['b'])
new_df.median()

d     1.0
f     7.0
g    54.0
h    64.0
dtype: float64
Run Code Online (Sandbox Code Playgroud)

这种行为有点意外,找到列e的中位数仍然有效:

new_df['e'].median()
1.0
Run Code Online (Sandbox Code Playgroud)

使用skipna=False并没有什么区别:

new_df.median(skipna=False)

d     1.0
f     7.0
g    54.0
h    64.0
dtype: float64
Run Code Online (Sandbox Code Playgroud)

(它适用于原始数据帧):

df.median(skipna=False)

b    21.75
d     1.00
e      NaN
f     7.00
g    54.00
h    64.00
dtype: float64
Run Code Online (Sandbox Code Playgroud)

列的数据类型eobject在这两个dfnew_df以及两个dataframes之间唯一的区别是new_df没有列b.将列添加回来new_df不能解决问题.这仅在b删除第一列时发生.如果column e是float或integer数据类型,则不会发生这种情况.

此行为存在于pandas==0.22.0pandas==0.24.1

现在有一个开放的GitHub问题,任何人都可以尝试解决这个问题!

Pro*_*osh 3

这似乎是一个错误。当我们将任何 df 分派到 时median,它会映射到内部_reduce函数。设置numeric_only为 时None,这将按系列计算中位数,并忽略失败(对于列c,例如中位数计算将失败。)并累积结果(请参阅_reducepandas 源 core/frame.py)。到目前为止还好。但是,当通过它将结果拼接在一起时,它会进行检查以推断结果是标量还是系列(因为median它当然是标量)。要执行此检查,它始终使用第一列(请参阅wrap_resultspandas 源 core/apply.py)。因此,如果第一列计算失败并且被跳过,则此检查失败,引发异常。这会触发后备方法,_reduce强制数据帧仅显示数字(删除带有 的任何列NaN)并重新计算中位数。

因此,在您的情况下,如果列 c (或中值计算将失败的任何其他数据类型,如文本)位于第一列中,则所有列也NaN将被删除以获取中值结果。设置skipna不会改变,因为错误在于第一个位置的非数字列如何触发强制仅数字计算。如果不在 pandas 代码库中修复它,我看不出有任何可能的修复。或者确保第一列始终能够成功进行中值计算。