在pandas Dataframe列中找到唯一行,其中第二列的所有值都是NaN

3

你好,我正在为以下问题苦苦挣扎:

给定一个带有 namevariable 两列的数据框,我想要创建两个列表:

  • list_names_nan 包含在变量列中所有值都是NaN的名称
  • list_names_not_nan 包含在变量列中至少有一个非NaN值的名称

以下是一个示例

import pandas
import numpy

df = pandas.DataFrame(data=[['x',1],['y',2],['x',4],['z',numpy.nan],
                            ['x',numpy.nan],['y',3],['x',numpy.nan],['z',numpy.nan],],
                            columns=['name','variable'])
df:
  name  variable
0    x       1.0
1    y       2.0
2    x       4.0
3    z       NaN
4    x       NaN
5    y       3.0
6    x       NaN
7    z       NaN

期望的输出应该是

list_names_nan = [z]
list_names_not_nan = [x,y]
2个回答

3
使用Series.isna创建一个布尔掩码,然后在此掩码上使用Series.groupby并使用all进行聚合,最后使用此掩码m过滤nannot_nan值:
m = df['variable'].isna().groupby(df['name']).all()
nan, not_nan = m[m].index.tolist(),  m[~m].index.tolist()

结果:

['z']  # nan
['x', 'y'] # not_nan

0

这里有另一种使用自定义聚合函数的方法:

agg = df.groupby('name').agg(lambda x: all(np.isnan(x))).reset_index()

这将生成一个聚合数据帧:
  name  variable
0    x     False
1    y     False
2    z      True

然后你可以获取那些是 False 或者 True 的名称。

list_names_nan = agg.loc[agg['variable']==True]['name'].tolist()
list_names_not_nan = agg.loc[agg['variable']==False]['name'].tolist()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接