Python Pandas中DataFrame的聚合?

3

我有一个如下的DataFrame:

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(意味着“not”或“oth”)的ID数量

能否帮我构建如下的DF?

enter image description here

2个回答

6
您可以使用条件掩码将 AC 以外的任何内容或np.nan替换为Other,并使用groupby.value_counts进行分组,然后使用unstackadd_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())

Anky,很好,但我能在.eq()中添加列的列表吗?例如,如果我想添加不止“ac”而是“ac”,“bc”等等,是否可以这样做? - dingaro
@jack55 是的,尝试使用isin而不是eq来匹配多个值:u = df['status'].where(df['status'].isin(["ac","bc"])|df['status'].isna(),"Other") - anky
1
@anky 可以尝试使用 crosstab,例如 pd.crosstab(df['ID'], df['status'].fillna('NaN')) - Shubham Sharma
1
太好了!谢谢你,我已经把最佳答案给了你! :) - dingaro
1
这太不可思议了,你是怎么想到的,Anky?我猜我对unstack函数不是很熟悉。 - MaxYarmolinsky
显示剩余2条评论

2

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

     (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

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