如何获取 pandas 交叉表来汇总多列的值?

How to get pandas crosstab to sum up values for multiple columns?

假设我们有一个 table 比如:

id    chr     val1     val2
...    A        2       10
...    B        4       20
...    A        3       30

...我们希望有这样的意外事件 table(按 chr 分组,因此使用 'A''B' 作为行索引然后将 val1val2 的值相加):

       val1    val2    total
A        5      40       45
B        4      20       24
total    9      60       69

我们怎样才能做到这一点?

pd.crosstab(index=df.chr, columns=["val1", "val2"]) 看起来很有前途,但它只计算行数而不对值求和。

我也尝试过(无数次)手动提供值...

pd.crosstab(
  index=df.chr.unique(),
  columns=["val1", "val2"],
  values=[
    df.groupby("chr")["val1"],
    df.groupby("chr")["val2"]
  ],
  aggfunc=sum
)

...但这总是以形状不匹配而告终,当我尝试通过 NumPy 重塑时:

values=np.array([
  df.groupby("chr")["val1"].values,
  df.groupby("chr")["val2"].values
].reshape(-1, 2)

...crosstab 告诉我它期望 1 个值而不是每行给定的两个值。

import pandas as pd

df = pd.DataFrame({'chr': {0: 'A', 1: 'B', 2: 'A'},
 'val1': {0: 2, 1: 4, 2: 3},
 'val2': {0: 10, 1: 20, 2: 30}})
# aggregate values by chr
df = df.groupby('chr').sum().reset_index()
df = df.set_index('chr')
# Column Total
df.loc['total', :] = df.sum()
# Row total
df['total'] = df.sum(axis=1)

输出

       val1     val2    total
chr         
A       5.0     40.0    45.0
B       4.0     20.0    24.0
total   9.0     60.0    69.0

你要的是pivot_table

table = pd.pivot_table(df, values=['val1','val2'], index=['char'], aggfunc=np.sum)
table['total'] = table['val1'] + table['val2']