我想对数据框中包含的每列的NaN进行计数,但是要忽略开头的NaN。
所以我的数据框具有以下结构:
import pandas as pd
import numpy as np
df=pd.DataFrame({'Date':
pd.date_range(pd.datetime.today().strftime("%m/%d/%Y"),periods=10).tolist(),
'Col1': [np.nan,np.nan,np.nan,4,5,6,7,np.nan,np.nan,np.nan],
'Col2': [np.nan,np.nan,np.nan,4,5,6,7,8,9,np.nan],
'Col3': [np.nan,2,3,4,np.nan,6,7,8,9,np.nan] })
df
Date Col1 Col2 Col3
0 2019-08-16 NaN NaN NaN
1 2019-08-17 NaN NaN 2.0
2 2019-08-18 NaN NaN 3.0
3 2019-08-19 4.0 4.0 4.0
4 2019-08-20 5.0 5.0 NaN
5 2019-08-21 6.0 6.0 6.0
6 2019-08-22 7.0 7.0 7.0
7 2019-08-23 NaN 8.0 8.0
8 2019-08-24 NaN 9.0 9.0
9 2019-08-25 NaN NaN NaN
所需的输出应该是一个数据帧,某物。喜欢:
Col1 Col2 Col3
3 1 2
答案 0 :(得分:1)
首先不带DataFrame.iloc
过滤所有列,然后用DataFrame.count
用NaN
s减少带有误配值的非nans值,并计算所有非nans值:
df1 = df.iloc[:, 1:]
a = df1.ffill().count() - df1.count()
或者:
df1 = df.iloc[:, 1:]
a = df1.isna().sum() - df1.ffill().isna().sum()
或者:
df1 = df.iloc[:, 1:]
a = df1.mask(df1.ffill().isna(), 1).isna().sum()
print (a)
Col1 3
Col2 1
Col3 2
dtype: int64
最后一次是否需要一行DataFrame:
df1 = a.to_frame(0).T
print (df1)
Col1 Col2 Col3
0 3 1 2
答案 1 :(得分:1)
您的df示例与您的输出示例不匹配。
设置:
df=pd.DataFrame({'Date':
pd.date_range(pd.datetime.today().strftime("%m/%d/%Y"),periods=10).tolist(),
'Col1': [np.nan,np.nan ,np.nan,4,5,6,7,np.nan,np.nan,np.nan],
'Col2': [np.nan,np.nan,np.nan,4,5,6,7,8,9,np.nan],
'Col3': [np.nan,2,3,4,np.nan,6,7,8,9,np.nan] })
解决方案:
df.iloc[:,1:].apply(lambda x: x.iloc[x.notna().idxmax():].isna().sum())
Col1 3
Col2 1
Col3 2
dtype: int64
正如@jezrael所指出的,如果列中的所有值均为nan,则此解决方案可能无法正常工作。
Jezrael的解决方案更加优雅。请用他的。
答案 2 :(得分:1)
一种解决方案是使用label
中的scipy.ndimage
函数来查找nan
的所有连续补丁,然后对标签超过1
的条目进行计数。
from scipy.ndimage import label
res = df.isnull().apply(lambda s: (label(s)[0] > 1).sum())
# Date 0
# Col1 3
# Col2 1
# Col3 2