Как перевернуть таблицу в pandas (PIVOT)

Есть Pandas DataFrame, который выглядит так:

     expr Therapy
0    100       A
1     96       A
2    101       A
3     95       A
4    103       A
5     99       A
6     97       A
7     96       A
8     98       A
9    106       A
10   106       A
11   104       A
12    95       A
13    95       A
14   105       A
15   100       B
16   100       B
17    95       B
18    84       B
19   101       B
20   101       B
21    95       B
22   106       B
23   105       B
24    97       B
25   103       B
26    94       B
27    94       B
28   100       B
29   107       B
30    91       C
31    96       C
32    94       C
33    96       C
34    91       C
35    85       C
36    98       C
37    93       C
38   100       C
39    85       C
40   101       C
41   101       C
42    90       C
43    98       C
44    97       C
45    92       D
46    85       D
47    95       D
48    89       D
49    91       D
50    91       D
51    99       D
52    94       D
53    97       D
54    94       D
55    87       D
56    93       D
57    96       D
58    92       D
59    90       D

Как сделать так, чтобы колонки были A и В, а данные в колонках были значениями expr для А и В соответственно. Прочитал про использование pivot, но выходит такая история:

Therapy      A      B      C     D
0        100.0    NaN    NaN   NaN
1         96.0    NaN    NaN   NaN
2        101.0    NaN    NaN   NaN
3         95.0    NaN    NaN   NaN
4        103.0    NaN    NaN   NaN
5         99.0    NaN    NaN   NaN
6         97.0    NaN    NaN   NaN
7         96.0    NaN    NaN   NaN
8         98.0    NaN    NaN   NaN
9        106.0    NaN    NaN   NaN
10       106.0    NaN    NaN   NaN
11       104.0    NaN    NaN   NaN
12        95.0    NaN    NaN   NaN
13        95.0    NaN    NaN   NaN
14       105.0    NaN    NaN   NaN
15         NaN  100.0    NaN   NaN
16         NaN  100.0    NaN   NaN
17         NaN   95.0    NaN   NaN
18         NaN   84.0    NaN   NaN
19         NaN  101.0    NaN   NaN
20         NaN  101.0    NaN   NaN
21         NaN   95.0    NaN   NaN
22         NaN  106.0    NaN   NaN
23         NaN  105.0    NaN   NaN
24         NaN   97.0    NaN   NaN
25         NaN  103.0    NaN   NaN
26         NaN   94.0    NaN   NaN
27         NaN   94.0    NaN   NaN
28         NaN  100.0    NaN   NaN
29         NaN  107.0    NaN   NaN
30         NaN    NaN   91.0   NaN
31         NaN    NaN   96.0   NaN
32         NaN    NaN   94.0   NaN
33         NaN    NaN   96.0   NaN
34         NaN    NaN   91.0   NaN
35         NaN    NaN   85.0   NaN
36         NaN    NaN   98.0   NaN
37         NaN    NaN   93.0   NaN
38         NaN    NaN  100.0   NaN
39         NaN    NaN   85.0   NaN
40         NaN    NaN  101.0   NaN
41         NaN    NaN  101.0   NaN
42         NaN    NaN   90.0   NaN
43         NaN    NaN   98.0   NaN
44         NaN    NaN   97.0   NaN
45         NaN    NaN    NaN  92.0
46         NaN    NaN    NaN  85.0
47         NaN    NaN    NaN  95.0
48         NaN    NaN    NaN  89.0
49         NaN    NaN    NaN  91.0
50         NaN    NaN    NaN  91.0
51         NaN    NaN    NaN  99.0
52         NaN    NaN    NaN  94.0
53         NaN    NaN    NaN  97.0
54         NaN    NaN    NaN  94.0
55         NaN    NaN    NaN  87.0
56         NaN    NaN    NaN  93.0
57         NaN    NaN    NaN  96.0
58         NaN    NaN    NaN  92.0
59         NaN    NaN    NaN  90.0

В чем проблема, и как правильно использовать данный метод (если вообще он тут нужен)?


Ответы (3 шт):

Автор решения: CrazyElf

Попробуйте так, чтобы сопоставить колонки с одинаковым expr:

df.pivot(index='expr', columns='Therapy', values='expr')

Примечание: если в полученной таблице будут пропущенные значения (NaN), то все значения таблицы автоматически будут преобразованы в float64, это особенности Pandas.

→ Ссылка
Автор решения: strawdog

попробуйте сделать так:

df = df.pivot_table(index=df.index, columns=['Therapy'], values='expr')
df = df.apply(lambda x: pd.Series(x.dropna().values))

Результат для вашего df будет:

Therapy      A      B      C     D
0        100.0  100.0   91.0  92.0
1         96.0  100.0   96.0  85.0
2        101.0   95.0   94.0  95.0
3         95.0   84.0   96.0  89.0
4        103.0  101.0   91.0  91.0
5         99.0  101.0   85.0  91.0
6         97.0   95.0   98.0  99.0
7         96.0  106.0   93.0  94.0
8         98.0  105.0  100.0  97.0
9        106.0   97.0   85.0  94.0
10       106.0  103.0  101.0  87.0
11       104.0   94.0  101.0  93.0
12        95.0   94.0   90.0  96.0
13        95.0  100.0   98.0  92.0
14       105.0  107.0   97.0  90.0
→ Ссылка
Автор решения: MaxU

Можно сделать так:

res = (df
       .assign(n=df.groupby("Therapy").cumcount())
       .pivot_table(index="n", columns="Therapy", values="expr", fill_value=0)
       .rename_axis(None))

результат:

In [11]: res
Out[11]:
Therapy    A    B    C   D
0        100  100   91  92
1         96  100   96  85
2        101   95   94  95
3         95   84   96  89
4        103  101   91  91
5         99  101   85  91
6         97   95   98  99
7         96  106   93  94
8         98  105  100  97
9        106   97   85  94
10       106  103  101  87
11       104   94  101  93
12        95   94   90  96
13        95  100   98  92
14       105  107   97  90
→ Ссылка