【问题标题】:Aggregation of DataFrame in Python Pandas?Python Pandas 中 DataFrame 的聚合?
【发布时间】:2021-04-14 19:19:14
【问题描述】:

我有如下数据框:

df = pd.DataFrame({"ID" : ["1", "1", "1", "2", "2", "2", "1"],
                   "status" : ["ac", "not", "not", "ac", np.NaN, "ac", "oth"]})

我需要使用如下列构建 DataFrame:

  1. NumberAcc - 状态为“ac”的 ID 编号
  2. NumberNaN - 状态 = NanN(缺失 -> np.nan)的 ID 数
  3. NumberOther - 状态不是“ac”或 np.nan 的 ID 编号(表示“not”或“oth”)

你能帮我像下面这样构建 DF 吗?

【问题讨论】:

    标签: python pandas dataframe sum aggregation


    【解决方案1】:

    您可以使用条件掩码将任何不是 ac 或 np.nan 的内容替换为 Othergroupby.value_counts ,然后使用 add_prefix 取消堆叠和格式化

    u = df['status'].where(df['status'].eq("ac")|df['status'].isna(),"Other")
    
    out = (u.groupby(df['ID']).value_counts(dropna=False).unstack(fill_value=0)
            .add_prefix("Number_").reset_index().rename_axis(None,axis=1))
    

    或者;

    a = pd.Series(np.select([df['status'].eq("ac"),df['status'].isna()],
                  ['acc',np.nan],'other'))
    out = (a.groupby(df['ID']).value_counts(dropna=True).unstack(fill_value=0)
            .add_prefix("Numnber_").reset_index())
    

    print(out)
    
      ID  Number_nan  Number_Other  Number_ac
    0  1           0             3          1
    1  2           1             0          2
    

    @Shubham 建议的类似逻辑,但使用交叉表:

    u = df['status'].where(df['status'].eq("ac")|df['status'].isna(),"Other")
    out = (pd.crosstab(df['ID'],u.fillna("NAN"),dropna=False)
       .add_prefix("Number_").rename_axis(None).reset_index())
    

    【讨论】:

    • 很糟糕,但我可以在 .eq() 中添加列列表吗?例如,如果我想添加的不仅仅是“ac”,例如 .eq("ac" ,"bc") 等等?
    • @jack55 是的,尝试isin insead of eq 获取多个值:u = df['status'].where(df['status'].isin(["ac","bc"])|df['status'].isna(),"Other")
    • @anky 可以试试crosstab 喜欢pd.crosstab(df['ID'], df['status'].fillna('NaN'))..
    • 太棒了!谢谢我给了你最好的答案! :)
    • 这太不可思议了,你怎么知道这个问题?猜猜我对 unstack 函数不太熟悉
    【解决方案2】:

    您可以通过assign 创建列,然后按“ID”分组并求和:

         (df.assign(NumberAcc=df.status.eq("ac"),
                    NumberNaN=df.status.isna(),
                    NumberOther=lambda df: ~(df.NumberAcc | df.NumberNaN))
            .groupby("ID")
            .sum())
    
        NumberAcc   NumberNaN   NumberOther
    ID          
    1       1           0           3
    2       2           1           0
    

    【讨论】:

      猜你喜欢
      • 2021-04-06
      • 2021-04-06
      • 2018-04-16
      • 1970-01-01
      • 1970-01-01
      • 2021-04-20
      • 1970-01-01
      • 2021-04-14
      • 2020-01-28
      相关资源
      最近更新 更多