Pandas:如何对行上的多个级别进行分组?

Nov*_*oll 6 python pandas

我有以下数据框

|----|----|
| A  | B  |
| a1 | b1 |
| a2 | b1 |
| a1 | b2 |
| a2 | b3 |
Run Code Online (Sandbox Code Playgroud)

我想按B计算每个A并得到以下结果:

|----|----|-------|
| A  | B  | Count |
| a1 | b1 |  1    |
|    | b2 |  1    |
|    | b3 |  NaN  |
| a2 | b1 |  1    |
|    | b2 |  NaN  |
|    | b3 |  1    |
Run Code Online (Sandbox Code Playgroud)

我通常这样做,df.groupby([B])[A].count()但在这种情况下,有点数据透视表对我来说很困惑

提前致谢。

更新时间:

df.info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 20422 entries, 180 to 96430
Data columns (total 2 columns):
B    20422 non-null object
A             20422 non-null object
dtypes: object(2)
memory usage: 478.6+ KB
Run Code Online (Sandbox Code Playgroud)

我得到df.groupby([B])[A].value_counts().unstack().stack(dropna=False).reset_index(name="Count")

|--|----|----|-------|
|  | A  | B  | Count |
|0 | a1 | b1 |  1    |
|1 | a1 | b2 |  1    |
|2 | a1 | b3 |  NaN  |
|3 | a2 | b1 |  1    |
|4 | a2 | b2 |  NaN  |
|5 | a2 | b3 |  1    |
Run Code Online (Sandbox Code Playgroud)

Nic*_*eli 5

1) 一种方法是对using"A"下元素的不同计数进行分组和计算。然后融合和with以获得所需的:"B"value_countsunstackstackdropna=FalseDF

df.groupby('A')['B'].value_counts().unstack().stack(dropna=False).reset_index(name="Count")
Run Code Online (Sandbox Code Playgroud)

2)pd.crosstab如果我们用np.NaN堆栈后替换零计数元素,也提供了一个很好的选择:

pd.crosstab(df['A'], df['B']).stack().replace({0:np.nan}).reset_index(name="Count")
Run Code Online (Sandbox Code Playgroud)

两种方法都会产生:

在此处输入图片说明


编辑1:

要具有分组键,"A"以某种格式显示(即保留第一次出现,同时用空字符串替换其余部分)

df_g = pd.crosstab(df['A'], df['B']).stack().replace({0:np.nan}).reset_index(name="Count")
df_g.loc[df_g.duplicated('A'), "A"] = ""
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

编辑2:

如果你想"A"作为一个单一的健康细胞成为多索引的一部分DF

df.groupby('A')['B'].value_counts().unstack().stack(dropna=False
                    ).reset_index(name="Count").set_index(['A', 'B'])
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明