按条件对数据框进行分组,并将值广播到分组中。

3

数据框:

STUD_ID   CLASS   GRADE  CATEGORY 
1         'Sci'    max  'Alpha' 
2         'Sci'    7    'Omega' 
3         'Sci'    9    'Alpha' 
4         'Sci'    3    'Alpha' 
5         'Sci'    9    'Alpha' 
7         'eng'    max  'Gamma' 
8         'eng'    5    'Gamma' 
9         'eng'    3    'Epsilon'
10        'Art'    3    'Lambda' 
11        'Art'    8    'Lambda' 
12        'Art'    max  undefined 
13        'Art'    1    undefined 
14        'Art'    5    undefined 

我想创建一个新的列名为CATEGORY_1,将GRADE最高的每个CLASS组中的CATEGORY值进行广播。请参见下面的结果df。
STUD_ID   CLASS   GRADE  CATEGORY CATEGORY_1
1         'Sci'    max  'Alpha' .   'Alpha'
2         'Sci'    7    'Omega' .   'Alpha'
3         'Sci'    9    'Alpha' .   'Alpha'
4         'Sci'    3    'Alpha' .   'Alpha'
5         'Sci'    9    'Alpha' .   'Alpha'
7         'eng'    max  'Gamma' .   'Gamma'
8         'eng'    5    'Gamma' .   'Gamma'
9         'eng'    3    'Epsilon'   'Gamma'
10        'Art'    3    'Lambda' .  undefined
11        'Art'    8    'Lambda' .  undefined
12        'Art'    max  undefined . undefined
13        'Art'    1    undefined . undefined
14        'Art'    5    undefined . undefined

我尝试过使用 groupby + transform,但是我无法想出该如何仅广播分类(CATEGORY)值,其中等级(GRADE)最大。

4个回答

5

因为提到了groupby+transform

这很困难,因为您的转换取决于不止一个列。这需要您的转换函数接受Series和整个DataFrame,然后您可以在组内对其进行子集操作(基于Series索引)。为此正常工作,您应该拥有唯一的索引。

def get_max_cat(grade, df):
    s = grade=='max'
    return df.loc[s[s].index, 'CATEGORY'].item()  # Assumes always one max

df['Category_1'] = df.groupby('CLASS').GRADE.transform(get_max_cat, df=df)

4

如果我理解正确,您可以通过字典映射来实现:

df['CATEGORY_1'] = df.CLASS.map(pd.Series(df[df.GRADE == 'max']['CATEGORY'].values,index=df[df.GRADE == 'max']['CLASS']).to_dict())

输出:

         CLASS GRADE   CATEGORY CATEGORY_1
STUD_ID                                   
1        'Sci'   max    'Alpha'    'Alpha'
2        'Sci'     7    'Omega'    'Alpha'
3        'Sci'     9    'Alpha'    'Alpha'
4        'Sci'     3    'Alpha'    'Alpha'
5        'Sci'     9    'Alpha'    'Alpha'
7        'eng'   max    'Gamma'    'Gamma'
8        'eng'     5    'Gamma'    'Gamma'
9        'eng'     3  'Epsilon'    'Gamma'
10       'Art'     3   'Lambda'  undefined
11       'Art'     8   'Lambda'  undefined
12       'Art'   max  undefined  undefined
13       'Art'     1  undefined  undefined
14       'Art'     5  undefined  undefined

3

您可以首先选择列“GRADE”中值为“max”的行,然后按照班级(CLASS) merge,例如:

df = df.merge( df[df.GRADE == 'max', ['CLASS','CATEGORY']], 
               on='CLASS, how='left',suffixes=('','_1'))

2
另一种方法是使用whereGRADECATEGORY而不是max转换为NaN。然后,对每个CLASS组应用ffillbfill。"最初的回答"
df['CATEGORY_1'] = df.CATEGORY.where(df.GRADE.eq('max')) \
                     .groupby(df.CLASS).apply(lambda x: x.ffill().bfill())


Out[1493]:
    STUD_ID  CLASS GRADE   CATEGORY CATEGORY_1
0         1  'Sci'   max    'Alpha'    'Alpha'
1         2  'Sci'     7    'Omega'    'Alpha'
2         3  'Sci'     9    'Alpha'    'Alpha'
3         4  'Sci'     3    'Alpha'    'Alpha'
4         5  'Sci'     9    'Alpha'    'Alpha'
5         7  'eng'   max    'Gamma'    'Gamma'
6         8  'eng'     5    'Gamma'    'Gamma'
7         9  'eng'     3  'Epsilon'    'Gamma'
8        10  'Art'     3   'Lambda'  undefined
9        11  'Art'     8   'Lambda'  undefined
10       12  'Art'   max  undefined  undefined
11       13  'Art'     1  undefined  undefined
12       14  'Art'     5  undefined  undefined

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