Pandas 旋转、取消堆叠或以其他方式将列转换为具有适当计数的 headers

Pandas Pivot, Unstack or otherwise transform column to headers with proper count

我的示例数据:

          Division    Region     Director    Month
   0      1           A          Smith       JAN
   1      1           B          Jones       JAN
   2      2           C          Williams    FEB
   3      3           D          Johnson     FEB
   4      1           B          Watkins     MAR

所需的中间输出是:

Division    Region     Director    JAN   FEB   MAR
1           A          Smith       1      0     0
1           B          Jones       1      0     0
2           C          Williams    0      1     0
3           D          Johnson     0      1     0
1           B          Watkins     0      0     1

理想情况下的最终输出:

Division    Region     Director    JAN   FEB   MAR
1           A          Smith       1      0     0
            B          Jones       1      0     0
                       Watkins     0      0     1
2           C          Williams    0      1     0
3           D          Johnson     0      1     0

我尝试过在 SS 和其他地方找到的 pivot、pivotable、unstack 和各种 groupby 组合。在中间版本或最终版本中,没有什么能让我得到我需要的东西。最终,一旦我可以获得 Pandas 以帮助将其变成我需要的形状,我将把它保存到最终用户的 excel 文件中。感谢您花点时间查看。

使用 pivot 并分配一个虚拟值以获得 values

>>> df.assign(value=1) \
      .pivot(index=['Division', 'Region', 'Director'], 
             columns='Month', values='value') \
      .fillna(0).astype(int)[df['Month'].unique()] \
      .rename_axis(columns=None).reset_index()

   Division Region  Director  JAN  FEB  MAR
0         1      A     Smith    1    0    0
1         1      B     Jones    1    0    0
2         1      B   Watkins    0    0    1
3         2      C  Williams    0    1    0
4         3      D   Johnson    0    1    0

更新

I get the following error (which one of my other attempts brought the same error message). Value error: index contains duplicate entries, cannot reshape

使用pivot_table而不是pivot:

>>> df.assign(value=1) \
      .pivot_table(index=['Division', 'Region', 'Director'],
                   columns='Month', values='value', aggfunc='first') \
      .fillna(0).astype(int)[df['Month'].unique()] \
      .rename_axis(columns=None).reset_index()

或使用pd.get_dummies:

pd.concat([df.drop('Month', 1), pd.get_dummies(df.Month)], axis=1)

   Division Region  Director  FEB  JAN  MAR
0         1      A     Smith    0    1    0
1         1      B     Jones    0    1    0
2         2      C  Williams    1    0    0
3         3      D   Johnson    1    0    0
4         1      B   Watkins    0    0    1

对于最终输出,您似乎只想 sort_values:

(pd.concat([df.drop('Month', 1), pd.get_dummies(df.Month)], axis=1)
   .sort_values(['Division', 'Region']))

   Division Region  Director  FEB  JAN  MAR
0         1      A     Smith    0    1    0
1         1      B     Jones    0    1    0
4         1      B   Watkins    0    0    1
2         2      C  Williams    1    0    0
3         3      D   Johnson    1    0    0