python - 如何根据Python中选择列右侧每行中的nan的数量对数据帧进行子集化?

标签 python python-3.x pandas numpy nan

我有一个数据框形式的订单簿,如下所示:

import pandas as pd
import numpy as np

months = list(range(1, 13))
li = list(map(str, months))
cols = ['ID']
cols.extend(li)

df = pd.DataFrame(np.random.randint(0,1000,size=(10, 13)), columns=cols)
df.loc[[1,2],'1':'12'] = np.nan
df.loc[3,'7':'12'] = np.nan
df.loc[5,'5':'12'] = np.nan
df.loc[7,'3':'8'] = np.nan
df.loc[9,'3':'10'] = np.nan

    ID      1      2      3      4      5      6      7      8      9     10     11     12
0  328   45.0  226.0  388.0  286.0  557.0  930.0  234.0  418.0  863.0  500.0  232.0  116.0
1  340    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN
2  865    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN
3  313  947.0  272.0  936.0  501.0  241.0  731.0    NaN    NaN    NaN    NaN    NaN    NaN
4  293  772.0  185.0    6.0  284.0  522.0  826.0  995.0  370.0   87.0  668.0  469.0   40.0
5  226   31.0  994.0  896.0  889.0    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN
6  622  128.0  337.0   67.0  763.0  999.0  853.0  172.0  927.0  460.0  602.0  134.0  115.0
7  454  407.0    1.0    NaN    NaN    NaN    NaN    NaN    NaN   33.0   60.0  112.0  127.0
8  538  968.0  924.0  113.0  162.0  416.0   16.0   88.0  631.0  516.0  593.0   65.0  574.0
9  501  949.0  709.0    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN  272.0  220.0

就目前情况而言,我循环遍历列,然后遍历行,根据左侧单元格中的值填充每个单元格。

假设我处于“5”月份,这意味着我只对数据帧的这一部分感兴趣:

    ID       5      6      7      8      9     10     11     12
0  328     557.0  930.0  234.0  418.0  863.0  500.0  232.0  116.0
1  340       NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN
2  865       NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN
3  313     241.0  731.0    NaN    NaN    NaN    NaN    NaN    NaN
4  293     522.0  826.0  995.0  370.0   87.0  668.0  469.0   40.0
5  226       NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN
6  622     999.0  853.0  172.0  927.0  460.0  602.0  134.0  115.0
7  454       NaN    NaN    NaN    NaN   33.0   60.0  112.0  127.0
8  538     416.0   16.0   88.0  631.0  516.0  593.0   65.0  574.0
9  501       NaN    NaN    NaN    NaN    NaN    NaN  272.0  220.0

给定变量 term_len = 6,是否有一种有效的方法来识别哪些 ID/索引有 6 个连续单元格,其中来自列“5”的 NaN?

我期望的是识别行 [1, 2, 5, 9]。不是索引 4,因为它只有 4 个 NaN;也不是索引 3,因为该行不是以 NaN 开头。

我能想到的唯一方法:

month = 5
subset = df.loc[:, str(month):]
term_len  = 6
idxs = pd.to_numeric(subset.apply(pd.Series.first_valid_index,axis=1))
idxsT = idxs - month - term_len
idxsT.index[(idxsT >= 0) | (idxsT.isna())]

Out: Int64Index([1, 2, 5, 9], dtype='int64')

是否有其他方法可以解决这个问题?

最佳答案

  1. 创建一个名为 m 的掩码,用于使用 df.iloc[:,6:11] 过滤那些特定列。
  2. 然后,您可以将 .isnull() 添加到掩码,这将为这些列中的所有单元格返回 True 或 False,具体取决于它们是否为 null。
  3. 掩码的最后一部分是获取 .sum 并传递 axis=1,这将为您提供 sum每行所有列的所有True值,因为True=1和False=0,因为True/False是 bool 数据类型。所以,m,为您提供所选列的一系列 True 值计数。
  4. 最后一步是根据此掩码简单地过滤整个数据帧 df = df[m == 5] 过滤器,筛选出具有 5 个 True 值的行,即全部为 NaN 对于指定的列。

代码:

m = df.iloc[:,6:11].isnull().sum(axis=1)
df = df[m == 5]

输出:

    ID  1       2       3   4   5   6   7   8   9   10  11      12
1   340 NaN     NaN     NaN NaN NaN NaN NaN NaN NaN NaN NaN     NaN
2   865 NaN     NaN     NaN NaN NaN NaN NaN NaN NaN NaN NaN     NaN
5   226 31.0    994.0   896.0   889.0   NaN NaN NaN NaN NaN     NaN NaN NaN
9   501 949.0   709.0   NaN NaN NaN NaN NaN NaN NaN NaN 272.0   220.0

关于python - 如何根据Python中选择列右侧每行中的nan的数量对数据帧进行子集化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63003822/

相关文章:

python - skmultiLearn 分类器预测始终返回 0

python - 如何在多种条件下编写Python三元运算符

python - 使用 matplotlib 的动画子图

python - 递归总是更新字典

python - 为什么 python 3.6's aiohttp' s 循环多次给出相同的结果?

c - Python C-API……如何用 C 编写 python 代码

python - 在 Pandas GroupBy 数据框中按 ID 计算两个日期之间的行数

python - 如何让pandas绘制在具有相同y轴范围的同一张图上

python - 相应地组合两列

python - 推荐使用 [python-lifter] 进行查询的嵌套数据结构