如何将 Pandas DataFrame 转换为 clustermap 的 MultiIndexed 形式?

How to transform Pandas DataFrame into MultiIndexed form for a clustermap?

我有一个数据框,它是一个观察列表,按 'name' 列分组。我很难将其转换为多索引格式。

我有类似的东西:

    name | ratio | DayOfWeek | HourOfDay
    foo  | 0.7   | Mon       | 0
    foo  | 0.2   | Mon       | 1
    foo  | 0.11  | Mon       | 2
    foo  | 0.45  | Mon       | 3
..
    foo  | 0.2   | Mon       | 23
    foo  | 0.1   | Tue       | 0
    foo  | 0.6   | Tue       | 1
    foo  | 0.2   | Tue       | 2
..
    foo  | 0.1   | Sun       | 23
    bar  | 0.2   | Mon       | 0
    bar  | 0.11  | Mon       | 1
..

等等。

我想要的是可以与 seaborn 集群图一起使用的东西,以显示每天(作为一个整体)'names' 的 'ratios' 与几天内特定时间之间的相关性。

例如我需要类似的东西(不确定是否正确,但这就是我尝试过的):

                      | foo  | bar | ...
DayOfWeek  HourOfDay  |
Mon        0          | 0.7  | 0.2 | ...
           1          | ...
           2          | ...
...
Tue        0          | 0.1  | ...
           1          | ...
...        2

一旦我有了它,我希望能够将它 xs() 成切片,供来自 seaborn 的热图/集群图使用。

您可以使用 set_index with unstack:

df = df.set_index(['DayOfWeek','HourOfDay','name'])['ratio'].unstack()
print (df)
name                  bar   foo
DayOfWeek HourOfDay            
Mon       0          0.20  0.70
          1          0.11  0.20
          2           NaN  0.11
          3           NaN  0.45
          23          NaN  0.20
Sun       23          NaN  0.10
Tue       0           NaN  0.10
          1           NaN  0.60
          2           NaN  0.20

但是如果重复项需要 pivot_table 以及一些聚合函数,例如 meansum...:[=​​21=]

print (df)
   name  ratio DayOfWeek  HourOfDay
0   foo   0.70       Mon          0 <- duplicate for same name, DayOfWeek and HourOfDay - 0.7
1   foo   0.90       Mon          0 <- duplicate for same name, DayOfWeek and HourOfDay - 0.9
2   foo   0.20       Mon          1
3   foo   0.11       Mon          2
4   foo   0.45       Mon          3
5   foo   0.20       Mon         23
6   foo   0.10       Tue          0
7   foo   0.60       Tue          1
8   foo   0.20       Tue          2
9   foo   0.10       Sun         23
10  bar   0.20       Mon          0
11  bar   0.11       Mon          1


df = df.pivot_table(index=['DayOfWeek','HourOfDay'], 
                    columns='name', 
                    values='ratio', 
                    aggfunc='mean')
print (df)

name                  bar   foo
DayOfWeek HourOfDay            
Mon       0          0.20  0.80 < (0.7 + 0.9)/2 = 0.8
          1          0.11  0.20
          2           NaN  0.11
          3           NaN  0.45
          23          NaN  0.20
Sun       23          NaN  0.10
Tue       0           NaN  0.10
          1           NaN  0.60
          2           NaN  0.20

替代groupby

df = df.groupby(['DayOfWeek','HourOfDay','name'])['ratio'].mean().unstack()
print (df)
name                  bar   foo
DayOfWeek HourOfDay            
Mon       0          0.20  0.80 < (0.7 + 0.9)/2 = 0.8
          1          0.11  0.20
          2           NaN  0.11
          3           NaN  0.45
          23          NaN  0.20
Sun       23          NaN  0.10
Tue       0           NaN  0.10
          1           NaN  0.60
          2           NaN  0.20