在 python 中计数 table 或频率 table

Count table or frequency table in python

我有以下数据框

import pandas as pd
import numpy as np

df = pd.DataFrame({
                   'val0': [-8.93, 1.68, 1.58, -1.2, 3.43, 4.25, 3.96, -0.52, -8.12, -5.05, -7.12, 11.99, 16.98, 17.15, 0.11, -7.32, -11.61, -12.22, -11.99, -8.37, -5.84, 1.09, -3.21, -1.42, -4.31, -1.18, 5.39, -7.01, -3.99, -9.08, 3.32, -1.48, -0.64, -1.09, -2.18, 0.32, -2.31, 1.32, -4.02, -4.11],
                    'val1' : [-1.0, 4.0, -193.0, -22.0, -193.0, 200.0, 63.0, 43.0, 5.0, 35.0, 40.0, -7.0, -20.0, -43.0, -50.0, -43.0, -20.0, 20.0, 40.0, 48.0, 22.0, 9.0, 11.0, 6.0, 55.0, -200.0, -52.0, -10.0, -5.0, 60.0, 135.0, 85.0, 75.0, 75.0, 90.0, -122.0, -62.0, -162.0, 122.0, 50.0],

})

如何创建频率 table 或计数 table 类似于下面随附的快照。

我已经展示了一些示例,例如,有一个条目在 Val1 的 0-25 范围内和 Val0 的 0 到 -1.6 范围内。同样,没有条目落在 Val1 的 0-25 范围和 Val0 的 -1.6 和 -3.2 范围内。 (我当然需要整个 table 填充)

此外,如下图所示 table 我想查看每个类别的 Val0 的平均值

Val0 的平均值

您可以cut()将数据放入 bin 中:

df['val0_bin'] = pd.cut(df.val0, -np.arange(0, 32, 1.6)[::-1]) # np.arange(-32, 0, 1.6) does not seem to work
df['val1_bin'] = pd.cut(df.val1, range(0, 300, 25))

然后 crosstab() 他们:

table1 = pd.crosstab(df.val1_bin, df.val0_bin)

# sort column bins to match question prompt
columns = df.val0_bin.unique().dropna().sort_values(ascending=False)
table1 = table1[columns]

# flip display of category bounds
categories = [f'[{c.right}, {c.left})' for c in table1.columns.categories]
table1.columns = table1.columns.rename_categories(categories)

# val0_bin    [-0.0, -1.6)  [-1.6, -3.2)  [-3.2, -4.8)  [-4.8, -6.4)  [-6.4, -8.0)  [-8.0, -9.6)  [-11.2, -12.8)
# val1_bin
# (0, 25]                1             0             1             1             0             1               1
# (25, 50]               1             0             1             1             1             1               1
# (50, 75]               2             0             1             0             0             1               0
# (75, 100]              1             1             0             0             0             0               0
# (100, 125]             0             0             1             0             0             0               0

对于平均 val0 交叉表,指定 aggfunc='mean'values=df.val0:

table2 = pd.crosstab(df.val1_bin, df.val0_bin, aggfunc='mean', values=df.val0).fillna(0)
table2 = table2[columns]
table2.columns = table2.columns.rename_categories(categories)

# val0_bin    [-0.0, -1.6)  [-1.6, -3.2)  [-3.2, -4.8)  [-4.8, -6.4)  [-6.4, -8.0)  [-8.0, -9.6)  [-11.2, -12.8)
# val1_bin
# (0, 25]           -1.420          0.00         -3.21         -5.84          0.00         -8.12          -12.22
# (25, 50]          -0.520          0.00         -4.11         -5.05         -7.12         -8.37          -11.99
# (50, 75]          -0.865          0.00         -4.31          0.00          0.00         -9.08            0.00
# (75, 100]         -1.480         -2.18          0.00          0.00          0.00          0.00            0.00
# (100, 125]         0.000          0.00         -4.02          0.00          0.00          0.00            0.00