【问题标题】:group by + case when in other column with pandas与熊猫在其他列中时按+ case分组
【发布时间】:2019-06-22 20:12:21
【问题描述】:

我有一个包含三列(CUST_ID、TOPIC、VALUE)的数据模型

data = pd.DataFrame({"CUST_ID":["C1", "C1", "C2", "C3", "C3"],
                       "TOPIC":["TOPIC1", "TOPIC2", "TOPIC2", "TOPIC1", "TOPIC2"],
                       "VALUE":[10, 15, 8, 5, 20]})

我想按 CUST_ID 分组,将“TOPIC”列转换为“TOPIC_a_VALUE”和“TOPIC_b_VALUE”两列

我知道用 SQL 怎么做,但是 pandas 怎么做呢?

SELECT CUST_ID,
       MAX(CASE WHEN TOPIC = "TOPIC1" THEN VALUE ELSE 0 END) AS TOPIC_a_VALUE
       MAX(CASE WHEN TOPIC = "TOPIC2" THEN VALUE ELSE 0 END) AS TOPIC_b_VALUE
FROM TABLE
GROUP BY CUST_ID

我想要的结果如下,

result = pd.DataFrame({"CUST_ID":["C1", "C2", "C3"],
                       "TOPIC_a_VALUE":[10, np.nan, 5],
                       "TOPIC_b_VALUE":[15, 8, 20]})

【问题讨论】:

  • 能否请您使用随机数据发布最终输出的样子
  • @Sumanth 我通过 pandas 数据框添加原始数据和结果
  • 原始数据中没有TOPIC = "a",请添加以便我们复制
  • @anky_91 我修改错字,谢谢

标签: sql python-3.x pandas group-by


【解决方案1】:

您可以通过以下方式使用groupby

df=data.pivot_table(index=['CUST_ID','TOPIC'],columns=['TOPIC']).reset_index()
df.columns=[''.join(col) for col in df.columns.values]

df1 = df.groupby('CUST_ID').ffill()\
        .groupby('CUST_ID').last()\
        .reset_index()

清理数据框

df1 = df1.drop(columns = ['TOPIC']).
rename(columns{'VALUETOPIC1':'TOPIC_a_VALUE','VALUETOPIC2':'TOPIC_b_VALUE'})

【讨论】:

    【解决方案2】:

    也许比其他建议的答案更具可读性,我会选择:

    data.groupby(['CUST_ID', 'TOPIC'])['VALUE'].max().unstack()
    # Output
    #TOPIC   TOPIC1 TOPIC2
    #CUST_ID              
    #C1        10.0   15.0
    #C2         NaN    8.0
    #C3         5.0   20.0
    

    如果您愿意,当然可以重命名列:

    .rename(columns={'TOPIC1': 'TOPIC_a_VALUE', 'TOPIC2': 'TOPIC_b_VALUE'})
    

    【讨论】:

    • 是的,这样更好。昨晚想不到这个。 +1
    【解决方案3】:

    IIUC 你需要这样的东西:

    df=data.pivot_table(index=['CUST_ID','TOPIC'],columns=['TOPIC']).reset_index()
    df.columns=[''.join(col) for col in df.columns.values]
    df.loc[df.CUST_ID.duplicated(keep=False)]=df.loc[df.CUST_ID.duplicated(keep=False)].bfill()
    df=df.drop_duplicates('CUST_ID')
    df=df.drop([col for col in df.columns if 'Key' in col],axis=1).reset_index(drop=True)
    
    print(df)
    
      CUST_ID   TOPIC  VALUETOPIC1  VALUETOPIC2
    0      C1  TOPIC1         10.0         15.0
    1      C2  TOPIC2          NaN          8.0
    2      C3  TOPIC1          5.0         20.0
    

    【讨论】:

      【解决方案4】:

      您的查询在 SQL 中没有意义。我假设你打算这样:

      SELECT CUST_ID,
             MAX(CASE WHEN TOPIC = 'a' THEN VALUE ELSE 0 END) AS TOPIC_a_VALUE
             MAX(CASE WHEN TOPIC = 'b' THEN VALUE ELSE 0 END) AS TOPIC_b_VALUE
      FROM TABLE
      GROUP BY CUST_ID;
      

      这对 Pandas 解决方案没有直接帮助,但至少查询是有意义的。

      【讨论】:

      • 想@Gordon Linoff,我忘记了激化功能。
      猜你喜欢
      • 2016-06-24
      • 2019-04-02
      • 2023-02-17
      • 1970-01-01
      • 1970-01-01
      • 2018-02-15
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多