【问题标题】:Using transform with condition within a dataframe在数据框中使用带有条件的转换
【发布时间】:2021-12-15 02:41:14
【问题描述】:

有以下df

import numpy as np
import random

i = ['dog', 'cat', 'rabbit', 'elephant'] * 20

df = pd.DataFrame(np.random.randn(len(i), 3), index=i, \
            columns=list('ABC')).rename_axis('animal').reset_index()
            
df.insert(1, 'type', pd.Series(random.choice(['X', 'Y']) \
                for _ in range(len(df))))

如果动物的类型是 X,我想要 A 列的 max ... 否则 A 列的 min,在单独的列中。

Apply lambda with group by 显示多索引数组,代码如下:

g = df.groupby(['animal', 'type'])
g.apply(lambda g: np.where (g.type == 'X', g.A.max(), g.A.min()))

有没有办法把它转换成一个系列,可以作为一列添加到 df...比如使用transform

【问题讨论】:

    标签: pandas transform


    【解决方案1】:

    这是你想要的吗?

    >>> df
    
         animal type     A     B     C
    0       cat    Y  0.96 -0.02 -0.14
    1       cat    Y -0.80  0.86  1.75
    2       dog    X  1.13 -0.49 -1.66
    3       dog    Y  0.84 -0.07  0.15
    4  elephant    X  0.13 -0.54  0.73
    5  elephant    Y  0.14  1.77  0.94
    6    rabbit    X -0.12 -0.39  0.05
    7    rabbit    X  0.58 -1.17  0.77
    
    >>> def max_min_A(g):
            animal, type_ = g.name 
            return np.where(type_ == 'X', g.max(), g.min())
    
    >>> df['new_col'] = df.groupby(['animal', 'type'])['A'].transform(max_min_A)
    
         animal type     A     B     C  new_col
    0       cat    Y  0.96 -0.02 -0.14    -0.80
    1       cat    Y -0.80  0.86  1.75    -0.80
    2       dog    X  1.13 -0.49 -1.66     1.13
    3       dog    Y  0.84 -0.07  0.15     0.84
    4  elephant    X  0.13 -0.54  0.73     0.13
    5  elephant    Y  0.14  1.77  0.94     0.14
    6    rabbit    X -0.12 -0.39  0.05     0.58
    7    rabbit    X  0.58 -1.17  0.77     0.58
    

    【讨论】:

    • 系列有一个name attribute,您可能知道。每个列组作为名称是组标签的系列传递给transform 函数(在此键中为元组('animal','type'))。当我明白这一点时我发现了它;)但它在 Notes 下的transformdocs 中(“每个组都被赋予属性'name',以防你需要知道你是哪个组工作。”)
    【解决方案2】:

    @HarryPlotter:谢谢name 信息。很高兴看到组的名称作为元组传播。如果不想使用某个功能,可以使用以下方法:

    df.assign(new_col=g.A.transform(lambda x: np.where(x.name[1] =='X', \
                x.max(), x.min()))) 
    # x.name[1] is used to select the second element of the tuple, which is `type`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      • 2019-07-27
      • 1970-01-01
      • 2020-01-15
      相关资源
      最近更新 更多