pd.pivot: tidy to wide dataframe 转换错误

pd.pivot: tidy to wide dataframe conversion error

我正在尝试使用 pd.pivot 函数将“整洁”数据帧 (df1) 转换为“宽”数据帧作为所需结果,但 运行 出现问题。

可以使用以下代码段重新创建整齐的数据框:

df1 = pd.DataFrame({"stud_id": ['1234', '1234', '1234', '1234', '1234', '1234', '1234', '1234','1234', '1234', '1234', '1234',
                     '8076', '8076', '8076', '8076', '8076', '8076', '8076', '8076', '8076'],
"period":['Q1', 'Q2', 'Q3', 'Q4', 'Q1', 'Q2', 'Q3', 'Q4','Q1', 'Q2', 'Q3', 'Q4',
         'Q2', 'Q3', 'Q4', 'Q2', 'Q3', 'Q4', 'Q2', 'Q3', 'Q4'],
"subject": ['clay', 'clay', 'clay', 'clay', 'feat', 'feat', 'feat', 'feat','tabl', 'tabl', 'tabl', 'tabl',
           'clay', 'clay', 'clay', 'feat', 'feat', 'feat', 'tabl', 'tabl', 'tabl'],
"score": [0.05, 0.05, 0.09, 0.03, 0.05, 0.45, 0.3, 0.2, 0.8, 0.56, 0.72, 0.72,
          0, 0.1, 0, 0.5, 0.5, 0, 0.8, 0, 0]
               })

“期望的结果”应该如下所示:

我主要尝试使用 pd.pivot 获得想要的结果,但收效甚微。示例代码和值错误如下所示:

df1.pivot(index=['stud_id', 'period'], columns='subject', values=['score'])
Value Error: Shape of passed values is (1, 21), indices imply (1, 2)`

作为替代方案,我尝试了以下代码,但也导致如下错误:

df1.pivot(index='stud_id', columns='subject', values=['score'])
ValueError: Index contains duplicate entries, cannot reshape

有人可以指导我找到解决方案吗?

pivot 等同于添加索引,然后适当地入栈或出栈。这意味着它也可以用作解决方法:

>>> df1.pivot(index=['stud_id', 'period'], columns='subject', values='score').reset_index()
subject stud_id period  clay  feat  tabl
0          1234     Q1  0.05  0.05  0.80
1          1234     Q2  0.05  0.45  0.56
2          1234     Q3  0.09  0.30  0.72
3          1234     Q4  0.03  0.20  0.72
4          8076     Q2  0.00  0.50  0.80
5          8076     Q3  0.10  0.50  0.00
6          8076     Q4  0.00  0.00  0.00
>>> df1.set_index(['stud_id', 'period', 'subject'])['score'].unstack('subject').reset_index()
subject stud_id period  clay  feat  tabl
0          1234     Q1  0.05  0.05  0.80
1          1234     Q2  0.05  0.45  0.56
2          1234     Q3  0.09  0.30  0.72
3          1234     Q4  0.03  0.20  0.72
4          8076     Q2  0.00  0.50  0.80
5          8076     Q3  0.10  0.50  0.00
6          8076     Q4  0.00  0.00  0.00

请注意,如果您将列 'score' 替换为列列表 ['score'],您会得到一个多索引作为列 - 这可能是问题所在。

在任何情况下,如果原始数据帧中的多个单元格映射到后者的单个帧,您将得到 Index contains duplicate entries,并且需要使用 pivot_table。在这里您将选择一个函数来聚合这些单元格(默认情况下 aggfunc=np.mean):

>>> df1.pivot_table(index='stud_id', columns='subject', values='score')
subject      clay      feat      tabl
stud_id                              
1234     0.055000  0.250000  0.700000
8076     0.033333  0.333333  0.266667
>>> df1.pivot_table(index='stud_id', columns='subject', values='score', aggfunc='min')
subject  clay  feat  tabl
stud_id                  
1234     0.03  0.05  0.56
8076     0.00  0.00  0.00