首页 > 解决方案 > python pandas set_index() 和 unstack 结果在 hive 中带有下划线的列,但 pivot_table() 有效

问题描述

与我之前问过的以下问题相关:Python pandas dataframe pivot only works with pivot_table() but not with set_index() and unstack()

我已经能够成功地旋转以下示例数据,同时使用set_index()withunstack()和 using pivot_table()withaggfunc=first参数。

样本数据

id  responseTime    label   answers
ABC 2018-06-24  Category_1  [3]
ABC 2018-06-24  Category_2  [10]
ABC 2018-06-24  Category_3  [10]
DEF 2018-06-25  Category_1  [7]
DEF 2018-06-25  Category_8  [10]
GHI 2018-06-28  Category_3  [7]

期望的输出:

id  responseTime    category_1  category_2 category_3 category_8
ABC  2018-06-24           [3]     [10]         [10]       NULL
DEF  2018-06-25           [7]     NULL         NULL       [10]
GHI  2018-06-28           NULL    NULL         [7]        NULL

代码:

#this works but having issues with reset_index so leaving it here as comment. 
#df=pdDF.pivot_table(index=['items_id','responseTime'], columns='label', values='answers', aggfunc='first')

df=pdDF.set_index(['items_id','responseTime','label']).unstack('label')

#reset the index so all columns can be preserved for table creation
df.reset_index(inplace=True)

#create pyspark dataframe from pandas dataframe after pivoting is done.
psDF=spark.createDataFrame(df)

#create hive table
psDF.write.mode('overwrite').saveAsTable('default.test_table')

当我将第二段代码与set_index()and一起使用时,结果输出在打印数据帧时unstack()具有额外的标头。answers当我从此数据框创建配置单元表时,这会导致重复列。

reset_index() 之前的数据帧头:

                                   answers
id  responseTime    category_1  category_2 category_3 category_8

reset_index 之后的数据框列:

('items_id', '')|('responseTime', '')|('answers', u'category_1')|('answers', u'category_2')|('answers', u'cateogry_3')|('answers', u'category_8')

Hive 列名称:

_'items_id'_''_     
_'responsetime'_''_
_'answers'_u'category_1'_
_'answers'_u'category_2'_
_'answers'_u'category_3'_
_'answers'_u'category_8'_

我相信这是因为unstack()创建了具有多个级别的分层列。有没有办法让answer级别消失并在数据框本身中删除这些垃圾下划线字符和answer引用,以便我可以创建正常的配置单元列?

标签: pythonpandasdataframehivepivot-table

解决方案


在这里回答我自己的问题。

我可以使用droplevel()函数从数据框中删除最顶层。

set_index()在and之后unstack(),我可以添加以下行以answer从数据框中删除级别。

df.columns = df.columns.droplevel(0)

在此之后,reset_index()可以调用以保留数据框中的所有列,就像上面的代码一样。

我的数据框列和配置单元列现在不包含带下划线的级别信息。

|items_id|responseTime|category_1|category_2|category_3|category_8|

可在以下位置获得更多参考droplevel()

Stackoverlfow 问题Pandas:从多级列索引中删除一个级别?

熊猫 APIhttps ://pandas.pydata.org/pandas-docs/stable/generated/pandas.MultiIndex.droplevel.html#pandas.MultiIndex.droplevel


推荐阅读