我有以下数据框
|----|----|
| A | B |
| a1 | b1 |
| a2 | b1 |
| a1 | b2 |
| a2 | b3 |
我希望按 B 计算 A 并获得以下结果:
|----|----|-------|
| A | B | Count |
| a1 | b1 | 1 |
| | b2 | 1 |
| | b3 | NaN |
| a2 | b1 | 1 |
| | b2 | NaN |
| | b3 | 1 |
我通常使用df.groupby([B])[A].count()
执行此操作,但在这种情况下使用有点数据透视表对我来说很困惑
提前致谢。
UPDT:
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
我和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 |
答案 0 :(得分:4)
1)一种方法是在"A"
上进行分组,并使用value_counts
计算"B"
下的元素的不同计数。然后将unstack
和stack
与dropna=False
融合,以获得所需的DF
:
df.groupby('A')['B'].value_counts().unstack().stack(dropna=False).reset_index(name="Count")
2)如果我们在堆叠后用np.NaN
替换零计数元素,pd.crosstab
也提供了一个很好的选择:
pd.crosstab(df['A'], df['B']).stack().replace({0:np.nan}).reset_index(name="Count")
两种方法都产生:
edit1:
要使分组键"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"] = ""
<强> EDIT2: 强>
如果您希望"A"
作为单个健康单元格成为多索引DF
的一部分:
df.groupby('A')['B'].value_counts().unstack().stack(dropna=False
).reset_index(name="Count").set_index(['A', 'B'])
答案 1 :(得分:1)
您可以对两列进行分组并访问每个组的大小:
df.groupby(['A', 'B']).size()
返回:
A B
a1 b1 1
b2 1
a2 b1 1
b3 1
dtype: int64
但是,对于不存在的组合,它不会给你NaN
。