考虑以下数据帧:
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(复制粘贴并使用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但是,如果删除列,然后找到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这种行为有点出乎意料,单独找到e列的中位数仍然有效:
new_df['e'].median()
1.0使用skipna=False不会有什么不同:
new_df.median(skipna=False)
d 1.0
f 7.0
g 54.0
h 64.0
dtype: float64(它对原始数据帧起作用):
df.median(skipna=False)
b 21.75
d 1.00
e NaN
f 7.00
g 54.00
h 64.00
dtype: float64列e的数据类型在df和new_df中都是object,这两个数据帧之间的唯一区别是new_df没有列b。将列重新添加到new_df中并不能解决问题。只有在删除第一列b时才会发生这种情况。如果列e是浮点型或整型数据类型,则不会发生这种情况。
此行为在pandas==0.22.0和pandas==0.24.1中都存在
现在有了一个open GitHub issue,任何人都可以尝试解决这个问题!
发布于 2019-02-21 17:24:10
这似乎是一个错误。当我们将任何df分派到median时,这映射到内部_reduce函数。将numeric_only设置为None时,这将按系列计算中位数,并忽略失败(对于c列,例如,中位数计算将失败)。并累积结果(参见pandas source core/frame.py中的_reduce )。到目前为止一切都还好。但是,在将结果拼接在一起时,它会进行检查,以推断结果是标量的还是序列的(对于median,当然是标量的)。为了完成这项检查,它总是使用第一列(参见pandas source core/apply.py中的wrap_results )。因此,如果第一个列计算失败并被跳过,则此检查将失败,并引发异常。这将触发_reduce中的回退方法,强制数据帧仅为数字(使用NaN删除任何列)并重新计算中间数。
因此,在您的示例中,如果列c(或任何其他中值计算将失败的数据类型,如text)在第一列中,则所有包含NaN的列也将被删除以获得中值结果。设置skipna不会改变,因为错误在于第一个位置的非数值列如何触发强制的仅数值计算。如果不在pandas代码库中修复它,我看不到任何修复的可能。或者确保第一列对于中位数计算总是成功。
https://stackoverflow.com/questions/54755354
复制相似问题