pandas 仅重塑两列

pandas reshape only two columns

鉴于此示例数据框:

Provider    Month    Active   Acute   Hospital   Total
Joe         January  0        1       0          1
Mary        February 1        3       5          9
Susie       January  2        2       4          8
Susie       January  3        0       0          3
Mary        February 4        3       3          10
Joe         February 1        0       4          5

我正在尝试重塑数据,但只重塑 Month 和 Total 列。我试过 pivot、pivot table、unstack 和 melt,但似乎没有任何组合起作用。所需的数据框输出在下面,“活动”值 totaled 在从月份列和所有其他值中获取的月份列名称下在他们的列 headers 下,如上面的 df:

Provider    January  Acute   Hospital   Total   February  Acute  Hospital  Total
Joe         0        1       0          1       1         0      4         5
Susie       5        2       4          11      0         0      0         0
Mary        0        0       0          0       5         6      8         19

因此,上述数据框中的“活动”值现在出现在月份名称下,其余部分保持原样。想法?我确信它是各种重塑工具的组合,可以让我到达那里,但我还不能建立这种联系。

我的第一个想法是你应该在列上有一个 MultiIndex 结果。 第一级应该是月份名称,第二级应该是您的来源名称 具有整数数据的列。 查看最终结果中的列名。

从创建月份列表开始:

months = ['January', 'February']

如果源DataFrame中有更多月份,请扩展上面的列表 以便它包括所有现有月份。

然后从源DataFrame创建一个辅助DataFrame——一个pivot_table:

wrk = df.pivot_table(index='Provider', columns='Month', aggfunc='sum',
    fill_value=0)

目前列中的级别顺序错误,因此下一步是 反转它:

wrk.columns = wrk.columns.swaplevel()

为了得到预期的结果,重新索引 wrk:

result = wrk.reindex(columns=pd.MultiIndex.from_product([
    months, ['Active', 'Acute', 'Hospital', 'Total']]), fill_value=0)

我在上次指令中添加了fill_value,以填补一个月 如果您的源数据未能包含本月的数据,则为零。 尝试例如将 'March' 添加到 个月 ,您将看到结果。

对于您的源数据,结果是:

         January                      February                     
          Active Acute Hospital Total   Active Acute Hospital Total
Provider                                                           
Joe            0     1        0     1        1     0        4     5
Mary           0     0        0     0        5     6        8    19
Susie          5     2        4    11        0     0        0     0

请注意,行的顺序是升序的,在我看来结果 应该就像上面一样(您的预期结果包含放置的行 以任意顺序)。

我建议使用 pivot_table 和 MultiIndex:

df2 = (    df.pivot_table(index='Provider', columns='Month', fill_value=0, aggfunc='sum', sort=False)
   .swaplevel(axis=1)
   .sort_index(axis=1, level='Month', sort_remaining=False)
 )

输出:

Month    February                      January                     
           Active Acute Hospital Total  Active Acute Hospital Total
Provider                                                           
Joe             1     0        4     5       0     1        0     1
Mary            5     6        8    19       0     0        0     0
Susie           0     0        0     0       5     2        4    11

如果您坚持使用提供的格式,您可以修改列 headers(但会有不明确的重复名称):

df2.columns = df2.columns.map(lambda x: x[0] if x[1]=='Active' else x[1])

输出:

          February  Acute  Hospital  Total  January  Acute  Hospital  Total
Provider                                                                   
Joe              1      0         4      5        0      1         0      1
Mary             5      6         8     19        0      0         0      0
Susie            0      0         0      0        5      2         4     11