Python 在数据帧上使用groupby和lambda函数时保留NaN值

Python 在数据帧上使用groupby和lambda函数时保留NaN值,python,pandas,dataframe,Python,Pandas,Dataframe,在此基础上,我有一个数据集: ChildID MotherID preDiabetes 0 20 455 No 1 20 455 Not documented 2 13 102 NaN 3 13 102 Yes 4 702 946 No 5 82 571 No 6 82 57

在此基础上,我有一个数据集:

    ChildID   MotherID   preDiabetes
0     20      455        No
1     20      455        Not documented
2     13      102        NaN
3     13      102        Yes
4     702     946        No
5     82      571        No
6     82      571        Yes
7     82      571        Not documented
8     60      530        NaN
我将其转换为以下内容,以便每位母亲对糖尿病前期有一个单一的值:

    ChildID   MotherID   preDiabetes
0   20        455        No
1   13        102        Yes
2   702       946        No
3   82        571        Yes
4   60        530        No
我通过应用以下逻辑实现了这一点:

如果某个特定的MotherID的preDiabetes==Yes,则将preDiabetes的值指定为Yes,而不考虑剩余的观察值 否则,如果糖尿病前期!=是对于特定的MotherID,我将为preDiabetes指定一个值No 然而,在再次思考这一点之后,我意识到我应该保留NaN值,以便稍后对其进行插补,而不仅仅是将其赋值为“否”。 因此,我应该将我的逻辑编辑为:

如果某个特定的MotherID的preDiabetes==Yes,则将preDiabetes的值指定为Yes,而不考虑剩余的观察值 否则,如果特定MotherID的preDiabetes的所有值==NaN,则为preDiabetes分配一个NaN值 否则,指定一个值为“否” 因此,在上表中,MotherID=530的值应为NaN,如:

    ChildID   MotherID   preDiabetes
0   20        455        No
1   13        102        Yes
2   702       946        No
3   82        571        Yes
4   60        530        NaN
我尝试使用以下代码行执行此操作:

df=df.groupby['MotherID','ChildID']['preDiabetes'].应用 lambda x:如果x.values中的“Yes”,则为“Yes”;如果x.values.all中的np.NaN,则为“No” 但是,运行这行代码会导致以下错误:

TypeError:“in”需要字符串作为左操作数,而不是浮点


如果你们能指出我做错了什么,我将不胜感激。谢谢。

您可以使用自定义功能:

def func(s):

    if s.eq('Yes').any():
        return 'Yes'
    elif s.isna().all():
        return np.nan
    else:
        return 'No'

df  = (df
       .groupby(['ChildID', 'MotherID'])
       .agg({'preDiabetes': func}))

print(df)

   ChildID  MotherID preDiabetes
0       13       102         Yes
1       20       455          No
2       60       530         NaN
3       82       571         Yes
4      702       946          No

您可以使用自定义函数执行以下操作:

def func(s):

    if s.eq('Yes').any():
        return 'Yes'
    elif s.isna().all():
        return np.nan
    else:
        return 'No'

df  = (df
       .groupby(['ChildID', 'MotherID'])
       .agg({'preDiabetes': func}))

print(df)

   ChildID  MotherID preDiabetes
0       13       102         Yes
1       20       455          No
2       60       530         NaN
3       82       571         Yes
4      702       946          No
您可以尝试:

import pandas as pd
import numpy as np
import io

data_string = """ChildID,MotherID,preDiabetes
20,455,No
20,455,Not documented
13,102,NaN
13,102,Yes
702,946,No
82,571,No
82,571,Yes
82,571,Not documented
60,530,NaN
"""

data = io.StringIO(data_string)
df = pd.read_csv(data, sep=',', na_values=['NaN'])
df.fillna('no_value', inplace=True)
df = df.groupby(['MotherID', 'ChildID'])['preDiabetes'].apply(
         lambda x: 'Yes' if 'Yes' in x.values else (np.NaN if 'no_value' in x.values.all() else 'No'))
df
结果:

MotherID  ChildID
102       13         Yes
455       20          No
530       60         NaN
571       82         Yes
946       702         No
Name: preDiabetes, dtype: object
您可以尝试:

import pandas as pd
import numpy as np
import io

data_string = """ChildID,MotherID,preDiabetes
20,455,No
20,455,Not documented
13,102,NaN
13,102,Yes
702,946,No
82,571,No
82,571,Yes
82,571,Not documented
60,530,NaN
"""

data = io.StringIO(data_string)
df = pd.read_csv(data, sep=',', na_values=['NaN'])
df.fillna('no_value', inplace=True)
df = df.groupby(['MotherID', 'ChildID'])['preDiabetes'].apply(
         lambda x: 'Yes' if 'Yes' in x.values else (np.NaN if 'no_value' in x.values.all() else 'No'))
df
结果:

MotherID  ChildID
102       13         Yes
455       20          No
530       60         NaN
571       82         Yes
946       702         No
Name: preDiabetes, dtype: object
尝试:

df['preDiabetes']=df['preDiabetes'].map{'Yes':1,'No':0}.fillna-1 df=df.groupby['MotherID','ChildID']['preDiabetes'].max.map{1:'Yes',0:'No',-1:'NaN'}.reset 第一行将预先指定的格式设置为数字,假设NaN是除-1表示的是或否之外的所有内容

第二行假设至少有一个糖尿病前期患者是“是”——我们为该组输出“是”。假设我们有No和NaN-我们输出No。假设所有的都是NaN,我们输出NaN

产出:

>>>df 母性-儿童性糖尿病前期 0 102 13是 145520号 2530 60南 3571 82是 4946702号 尝试:

df['preDiabetes']=df['preDiabetes'].map{'Yes':1,'No':0}.fillna-1 df=df.groupby['MotherID','ChildID']['preDiabetes'].max.map{1:'Yes',0:'No',-1:'NaN'}.reset 第一行将预先指定的格式设置为数字,假设NaN是除-1表示的是或否之外的所有内容

第二行假设至少有一个糖尿病前期患者是“是”——我们为该组输出“是”。假设我们有No和NaN-我们输出No。假设所有的都是NaN,我们输出NaN

产出:

>>>df 母性-儿童性糖尿病前期 0 102 13是 145520号 2530 60南 3571 82是 4946702号
啊,好吧,这只是一个NaN值的例子,应该转换成字符串,明白了吗!这对我很有效,谢谢,我接受了这个答案。啊,好吧,这只是一个NaN值的例子,应该转换成字符串,明白了!这对我有用,谢谢,我接受了这个答案。