在所有列中查找带有NaN的pandas Groupby

时间:2018-01-19 16:16:12

标签: python pandas

假设我们设置了一个DataFrame,如下所示:

df = pd.DataFrame()
df['ID'] = [432, 601,  601, 383, 887, 887, 944,  68, 195, 724, 408, 351]
df['Details'] = [362,  85, 338, 332, 712, 932, 797, 365, 837,  66, 721, 695]
df['Tests'] = [769, np.nan, np.nan,  np.nan, 988, 496,   7, 408, np.nan, 417, 287, 723]
df['Size'] = [877,  np.nan,  np.nan, np.nan, 550, 967, 646, 654,  76, 185, np.nan, 635]

df['GroupID']=0
unique_ids = df.drop_duplicates(['ID']).index
df.loc[unique_ids, 'GroupID'] = 1
df['GroupID'] = df['GroupID'].cumsum()

结果df:

    ID  Details Tests   Size    GroupID
0   432 362     769.0   877.0   1
1   601 85      NaN     NaN     2
2   601 338     NaN     NaN     2
3   383 332     NaN     NaN     3
4   887 712     988.0   550.0   4
5   887 932     496.0   967.0   4
6   944 797     7.0     646.0   5
7   68  365     408.0   654.0   6
8   195 837     NaN     76.0    7
9   724 66      417.0   185.0   8
10  408 721     287.0   NaN     9
11  351 695     723.0   635.0   10

如何为该群组的所有成员找到['Tests', 'Size'] NaN的位置(即具有相同的GroupID)。对于此示例,答案应为GroupID = (2,3)ID = 601, 383

我的数据主要是dtype object - 所以主要是字符串(所以TestsSize都是字符串)。

2 个答案:

答案 0 :(得分:1)

另一种方式:

df_out = df[df.groupby('GroupID')[['Tests','Size']].transform('count').sum(1).eq(0)]

和以下相同的逻辑来获取GroupID或ID

注意:count不计算NaN值,因此我们检查计数等于零并求和以查看该组中是否所有都是NaN。

正在使用:

df_out = df.groupby('GroupID').filter(lambda x: x[['Tests','Size']].isnull().all().all())

    ID  Details  Tests  Size  GroupID
1  601       85    NaN   NaN        2
2  601      338    NaN   NaN        2
3  383      332    NaN   NaN        3

然后,

df_out.ID.unique().tolist()

输出:

[601, 383]

OR

df_out.GroupID.unique().tolist()

输出:

[2, 3]

答案 1 :(得分:0)

你可以查看dropna,并在这里使用thresh,它将返回需要多少非纳米值

df.GroupID[~df.GroupID.isin(df.dropna(thresh=df.shape[1]-1).GroupID)].unique()
Out[204]: array([2, 3], dtype=int64)