Python NaN最长批次的返回索引

Python NaN最长批次的返回索引,python,pandas,dataframe,missing-data,Python,Pandas,Dataframe,Missing Data,我有一个按两列排序的数据框:“ID”和一个日期列。 该表中有大量缺失值,我感兴趣的是了解缺失值是如何分布的:它们是否主要集中在一个“ID”上,所有ID是否在开始时都有缺失值,例如(日期),缺失值是否无关等 经过groupby ID+缺失值计数后,我使用了missingno包,它被证明是有用的,这是我得到的结果(清理列名): 从图中可以看出,似乎有特定批次的行中缺少了大多数列。 例如,如果您查看箭头,我可能可以大致估计要搜索的索引的值(~idx=750000),但这并不实际,因为还有其他实例发生了

我有一个按两列排序的数据框:“ID”和一个日期列。
该表中有大量缺失值,我感兴趣的是了解缺失值是如何分布的:它们是否主要集中在一个“ID”上,所有ID是否在开始时都有缺失值,例如(日期),缺失值是否无关等

经过groupby ID+缺失值计数后,我使用了missingno包,它被证明是有用的,这是我得到的结果(清理列名):

从图中可以看出,似乎有特定批次的行中缺少了大多数列。 例如,如果您查看箭头,我可能可以大致估计要搜索的索引的值(~idx=750000),但这并不实际,因为还有其他实例发生了相同的情况。
我想要的是一个函数
batches\u missing(cols,n\u rows)
,它获取列列表和int
n\u rows
,并返回所有批的元组列表[(index\u start\u batch1,index\u end\u batch1),…],其中给定列包含多行连续缺失值

通过一个模拟示例:

df=pd.DataFrame({'col1':[1,2,np.nan,np.nan,np.nan,np.nan,2,2,np.nan,np.nan,np.nan],
“col2”:[9,7,np.nan,np.nan,np.nan,np.nan,0,np.nan,np.nan,np.nan,np.nan],
'col3':[11,12,13,np.nan,1,2,3,np.nan,1,2,3]})
批次\u缺失(['col1','col2'],3)
将返回
[(2,5)、(8,10)]

考虑到实际数据相当大(1百万行),这能有效地做到吗?我也非常有兴趣了解分析缺失数据的其他方法,因此非常感谢阅读材料/链接


谢谢大家。

您可以按行计数,查看哪些行都是NAs,给定选定的列:

rowwise_tally = df[['col1','col2']].isna().apply(all,axis=1)

0     False
1     False
2      True
3      True
4      True
5      True
6     False
7     False
8      True
9      True
10     True
现在,您可以将此运行分组:

grp = rowwise_tally.diff().cumsum().fillna(0)
0     0.0
1     0.0
2     1.0
3     1.0
4     1.0
5     1.0
6     2.0
7     2.0
8     3.0
9     3.0
10    3.0
然后计算每个组中的nas数量,并获得开始和结束:

na_counts = rowwise_tally.groupby(grp).sum()
pos = pd.Series(np.arange(len(df))).groupby(grp).agg([np.min, np.max])
pos[na_counts>=3].to_numpy()

array([[ 2,  5],
       [ 8, 10]])
也许有更好的方法来获得这个职位,而不是像我那样使用pd.Series。现在,将其包装成一个函数:

def fun(data,cols,minlen):
    rowwise_tally = data[cols].isna().apply(all,axis=1)
    grp = rowwise_tally.diff().cumsum().fillna(0)
    na_counts = rowwise_tally.groupby(grp).sum()
    pos = pd.Series(np.arange(len(data))).groupby(grp).agg([np.min, np.max])
    return pos[na_counts>=minlen].to_numpy()

fun(df,['col1','col2'],3)

通过添加一个最小的可复制示例并解释我也有兴趣讨论除了简单的计数/百分比之外还有哪些其他潜在的方法来探索缺失的数据,从而修复了这个问题。