AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79076480
Accepted
Derek
Derek
Asked: 2024-10-11 08:13:27 +0800 CST2024-10-11 08:13:27 +0800 CST 2024-10-11 08:13:27 +0800 CST

Agrupar e agregar com base na condição

  • 772

Meus dados de entrada:

df=pd.DataFrame({'ID':['A','B','C','D'],
                 'Group':['group1','group1','group2','group2'],
                 'Flag_1':[1,0,0,1],
                 'Flag_2':[1,1,0,1],
                 'Value':[30,40,60,70]
                })

Estou tentando somar "Valor" por grupo quando o sinalizador é igual a 1. Minha saída esperada é:

df_value_group=pd.DataFrame({
                 'Flag_1 Sum':[1,1],
                 'Flag_2 Sum':[2,1],
                 'Value_1 Sum':[30,70],
                 'Value_2 Sum':[70,70]},                 
    index=['group1','group2'])

Eu tentei isso, mas ele me gera um erro AssertionError principalmente devido às duas últimas funções lambda.

df.groupby('Group').agg(
    **{ 'Flag_1 Sum': ('Flag_1','sum'),
        'Flag_2 Sum': ('Flag_2','sum'),
        'Value_1 Sum': ('Flag_1', lambda col: df.loc[col.eq(1), 'Value'].sum()),
        'Value_2 Sum': ('Flag_2', lambda col: df.loc[col.eq(1), 'Value'].sum())
})

python
  • 4 4 respostas
  • 68 Views

4 respostas

  • Voted
  1. sammywemmy
    2024-10-11T08:40:12+08:002024-10-11T08:40:12+08:00

    Uma forma mais eficiente é calcular os booleanos antes de agrupar:

    flags=df.assign(value_1_sum=df.loc[df.Flag_1.eq(1),'Value'],   
                    value_2_sum = df.loc[df.Flag_2.eq(1),'Value'])
    
    flags
    
      ID   Group  Flag_1  Flag_2  Value  value_1_sum  value_2_sum
    0  A  group1       1       1     30         30.0         30.0
    1  B  group1       0       1     40          NaN         40.0
    2  C  group2       0       0     60          NaN          NaN
    3  D  group2       1       1     70         70.0         70.0
    
    flags.groupby('Group').sum(numeric_only=True)
            Flag_1  Flag_2  Value  value_1_sum  value_2_sum
    Group
    group1       1       2     70         30.0         70.0
    group2       1       1    130         70.0         70.0
    
    • 1
  2. Best Answer
    mozway
    2024-10-11T13:25:55+08:002024-10-11T13:25:55+08:00

    Para uma abordagem genérica, você pode usar uma groupby.aggagregação personalizada (nomeada):

    cols = df.columns[df.columns.str.startswith('Flag_')]
    val = df['Value']
    
    out = (df.groupby('Group', as_index=False)
             .agg(**({f'{c} Sum': (c, lambda x: x.sum()) for c in cols}
                    |{f'Value{c[4:]} Sum': (c, lambda x: val[x.index][x==1].sum())
                      for c in cols}
                    )
                 )
          )
    

    NB. lambda x: val[x.index][x==1].sum()poderia ser substituído por lambda x: val.where(x==1).sum().

    Ou remodelar com melte agregar com pivot_table:

    tmp = (df
       .melt(['ID', 'Group', 'Value'], var_name='flag', value_name='bool')
       .query('bool == 1')
       .pivot_table(index='Group',
                    columns='flag',
                    aggfunc='sum',
                    fill_value=0,
                    )
     )
    
    out = (pd.concat([tmp['bool'],
                      tmp['Value'].rename(columns=lambda x: x.replace('Flag', 'Value'))
                      ], axis=1)
             .reset_index()
             .rename_axis(columns=None)
           )
    

    Saída:

        Group  Flag_1  Flag_2  Value_1  Value_2
    0  group1       1       2       30       70
    1  group2       1       1       70       70
    
    • 1
  3. e-motta
    2024-10-11T08:30:58+08:002024-10-11T08:30:58+08:00

    Você quer agregar mais de 'Value', não'Flag_X'

    df_value_group = df.groupby('Group').agg(
        **{ 'Flag_1 Sum': ('Flag_1','sum'),
            'Flag_2 Sum': ('Flag_2','sum'),
            'Value_1 Sum': ('Value', lambda x: x[df['Flag_1'] == 1].sum()),
            'Value_2 Sum': ('Value', lambda x: x[df['Flag_2'] == 1].sum())
    })
    
            Flag_1 Sum  Flag_2 Sum  Value_1 Sum  Value_2 Sum
    Group                                                   
    group1           1           2           30           70
    group2           1           1           70           70
    
    • 0
  4. Panda Kim
    2024-10-11T08:48:49+08:002024-10-11T08:48:49+08:00

    Crie uma função lambda com a função where

    cond1 = df['Flag_1'].eq(1)
    cond2 = df['Flag_2'].eq(1)
    
    out = df.groupby('Group').agg(
        **{ 'Flag_1 Sum': ('Flag_1','sum'),
            'Flag_2 Sum': ('Flag_2','sum'),
            'Value_1 Sum': ('Value', lambda x: x.where(cond1).sum()),
            'Value_2 Sum': ('Value', lambda x: x.where(cond2).sum())
    })
    

    fora:

            Flag_1 Sum  Flag_2 Sum  Value_1 Sum  Value_2 Sum
    Group                                                   
    group1           1           2           30           70
    group2           1           1           70           70
    

    Se houver muitas colunas que correspondem a Flag, ou se a linha inteira for longa e a eficiência for importante, é melhor criar um groupby para cada uma e então usar a função concat .

    cols = df.columns[df.columns.str.contains('Flag')]
    
    out = pd.concat([
        df.groupby('Group')[cols].sum().add_suffix(' Sum'),
        df[cols].mul(df['Value'], axis=0)
        .groupby(df['Group']).sum()
        .rename(lambda x: x.replace('Flag', 'Value') + ' Sum', axis=1)
    ], axis=1)
    

    mesmo resultado

    • 0

relate perguntas

  • Como divido o loop for em 3 quadros de dados individuais?

  • Como verificar se todas as colunas flutuantes em um Pandas DataFrame são aproximadamente iguais ou próximas

  • Como funciona o "load_dataset", já que não está detectando arquivos de exemplo?

  • Por que a comparação de string pandas.eval() retorna False

  • Python tkinter/ ttkboostrap dateentry não funciona quando no estado somente leitura

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve