首页 > 解决方案 > 如果连续 nan 的数量达到给定列的阈值 N,则在 pandas 数据框中查找 nan 值的第一行和最后一行索引?

问题描述

有一个 80 行 6 列的 pandas 数据框。有些列中有 nan 值。假设如果给定列中连续 nan 值的数量超过 10,那么我们必须对这些 nan 块的值做一些事情。所以,我的问题是如何提取与这些大块 nan 的开始和结束相对应的行索引?

标签: python-3.xpandasnumpy

解决方案


设置

让我们假设以下示例输入:

np.random.seed(3)
df = pd.DataFrame(np.random.choice([0,1], p=[0.7, 0.3], size=(80,6)))
df = df.mask(df.eq(0))
df.head(15)

输入:

      0    1    2    3    4    5
0   NaN  1.0  NaN  NaN  1.0  1.0
1   NaN  NaN  NaN  NaN  NaN  NaN
2   NaN  NaN  NaN  NaN  NaN  NaN
3   NaN  NaN  NaN  NaN  NaN  NaN
4   NaN  1.0  NaN  NaN  NaN  1.0
5   1.0  NaN  1.0  1.0  NaN  NaN
6   NaN  NaN  NaN  NaN  NaN  NaN
7   NaN  NaN  NaN  1.0  NaN  NaN
8   NaN  NaN  NaN  NaN  NaN  NaN
9   NaN  NaN  1.0  1.0  NaN  NaN
10  NaN  NaN  NaN  NaN  NaN  NaN
11  NaN  NaN  1.0  NaN  NaN  NaN
12  1.0  NaN  NaN  NaN  NaN  NaN
13  NaN  NaN  NaN  NaN  NaN  1.0
14  NaN  NaN  1.0  NaN  1.0  1.0
...
79  1.0  NaN  NaN  NaN  NaN  NaN

计算连续的 NaN 长度

您可以使用 计算掩码isna,然后使用 的组合生成一个组mask.ne(mask.shift())cumsum并使用 对其进行掩码where。最后应用groupby转换'size'来获得连续 NaN 的数量:

mask = df.isna()

df_na_sizes = (mask.ne(mask.shift()).cumsum()
                   .where(mask)
                   .apply(lambda c: c.groupby(c).transform('size'))
               )

输出:

      0     1    2    3     4    5
0   5.0   NaN  5.0  5.0   NaN  NaN
1   5.0   3.0  5.0  5.0  13.0  3.0
2   5.0   3.0  5.0  5.0  13.0  3.0
3   5.0   3.0  5.0  5.0  13.0  3.0
4   5.0   NaN  5.0  5.0  13.0  NaN
5   NaN  12.0  NaN  NaN  13.0  8.0
6   6.0  12.0  3.0  1.0  13.0  8.0
7   6.0  12.0  3.0  NaN  13.0  8.0
8   6.0  12.0  3.0  1.0  13.0  8.0
9   6.0  12.0  NaN  NaN  13.0  8.0
10  6.0  12.0  1.0  5.0  13.0  8.0
11  6.0  12.0  NaN  5.0  13.0  8.0
12  NaN  12.0  2.0  5.0  13.0  8.0
13  2.0  12.0  2.0  5.0  13.0  NaN
14  2.0  12.0  NaN  5.0   NaN  NaN
    ...
79  NaN   1.0  2.0  5.0   4.0  1.0

使用我们的掩码进行过滤

现在您可以使用它来按组大小进行选择,例如,如果连续的 NaN 等于或大于 10,我们将 NaN 替换为 'XX':

>>> df.mask(df_na_sizes.ge(10), 'XX')
      0    1    2    3    4    5
0   NaN  1.0  NaN  NaN  1.0  1.0
1   NaN  NaN  NaN  NaN   XX  NaN
2   NaN  NaN  NaN  NaN   XX  NaN
3   NaN  NaN  NaN  NaN   XX  NaN
4   NaN  1.0  NaN  NaN   XX  1.0
5   1.0   XX  1.0  1.0   XX  NaN
6   NaN   XX  NaN  NaN   XX  NaN
7   NaN   XX  NaN  1.0   XX  NaN
8   NaN   XX  NaN  NaN   XX  NaN
9   NaN   XX  1.0  1.0   XX  NaN
10  NaN   XX  NaN  NaN   XX  NaN
11  NaN   XX  1.0  NaN   XX  NaN
12  1.0   XX  NaN  NaN   XX  NaN
13  NaN   XX  NaN  NaN   XX  1.0
14  NaN   XX  1.0  NaN  1.0  1.0
...
79  1.0  NaN  NaN  NaN  NaN  NaN

推荐阅读