我有一个数据框形式的订单簿,如下所示:
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')
是否有其他方法可以解决这个问题?
最佳答案
- 创建一个名为
m
的掩码,用于使用df.iloc[:,6:11]
过滤那些特定列。 - 然后,您可以将
.isnull()
添加到掩码,这将为这些列中的所有单元格返回 True 或 False,具体取决于它们是否为 null。 - 掩码的最后一部分是获取
.sum
并传递axis=1
,这将为您提供sum
每行所有列的所有True
值,因为True=1和False=0,因为True/False是 bool 数据类型。所以,m
,为您提供所选列的一系列 True 值计数。 - 最后一步是根据此掩码简单地过滤整个数据帧
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/