NaN的处理

4 投票
2 回答
2149 浏览
提问于 2025-04-18 05:50

我在理解 pandas 和 numpy 如何处理 NaN 值时遇到了一些困难。我正在从一个 pandas 数据框中提取子集,以便计算 t 统计量。例如,我想知道 x1 值为 A 的组和 x1 值为 B 的组在 x2 的平均值上是否有显著差异(抱歉没有提供一个可以运行的例子,但我不知道如何重现我数据框中出现的 NaN 值,原始数据是通过 read_csv 读取的,csv 文件用 NA 来表示缺失值):

import numpy as np
import pandas as pd
import scipy.stats as st
A = data[data['x1']=='A']['x2']
B = data[data['x1']=='B'].x2
A

2      3
3      1
5      2
6      3
10     3
12     2
15     2
16     0
21     0
24     1
25     1
28   NaN
31     0
32     3
...
677     0
681   NaN
682     3
683     1
686     2
Name: praxiserf, Length: 335, dtype: float64

也就是说,我有两个 pandas.core.series.Series 对象,我想对它们进行 t 检验。然而,使用

st.ttest_ind(A, B)

返回:

(array(nan), nan)

我猜这和 ttest_ind 接受数组作为输入有关,而在将系列转换为数组时,NaN 值似乎出现了问题。如果我尝试计算原始系列的平均值,我得到:

A.mean(), B.mean()

1.5802, 1.2

但是,当我尝试将系列转换为数组时,我得到:

A_array = np.asarray(A)
A_array

array([ 3., 1., 2., 3., 3., 2., 2., 0., 0., 1., 1.,
        nan, 0., 3., ..., 1., nan, 0., 3. ])

也就是说,NaN 变成了 nan,而计算平均值就不再有效了:

A.mean()

nan

那么,缺失值应该如何处理,以确保我仍然可以对系列/数组进行计算呢?

2 个回答

1

ttest_ind这个函数有一个叫“nan_policy”的参数,用来决定怎么处理那些“nan”(也就是“不是一个数字”的意思)。默认情况下,nan_policy是“propagate”,这意味着如果输入中有任何一个值是nan,结果也会是nan。“raise”则会在输入中有nan时抛出错误。而“omit”会忽略掉nan。

st.ttest_ind(A, B, nan_policy="omit")

这样的话,应该能给你一个不是nan的结果。

5

pandas使用的代码和bottleneck里的nanmean函数是一样的,我想这就是它能自动忽略nan值的原因。而numpy则不会为你处理这些nan值。不过,你真正想做的,是把这两个数据系列中的nan值遮住,然后把处理后的数据传给t检验:

mask = numpy.logical_and(numpy.isfinite(A), numpy.isfinite(B))
st.ttest_ind(A[mask], B[mask])

撰写回答