如何解开pandas数据帧

时间:2016-12-14 12:13:30

标签: python-2.7 pandas

我有一个如下数据框,我想在这里保留一个最好的评级栏。

原始DataFrame:

skunumber   category    overallrating   rating  reviews
123          Cat1          1             1        20
124          cat1          2             2        23

因为我正在融化数据帧并将整体重命名为评级。最后删除重复项,如果有的话,我想再次转换融化的数据帧原始格式。

融合数据框看起来像这样:

skunumber   category    attribute   attributeRawValue
123         Cat1      overallrating        1
124         cat1      overallrating        3
123         Cat1        rating             1
124         cat1        rating             2
123         Cat1        reviews            20
124         cat1        reviews            23

DataFrame在将整体重命名为评级并删除重复项之后看起来像。

skunumber   category    attribute   attributeRawValue
123         Cat1        rating             1
124         cat1        rating             2
123         Cat1        reviews            20
124         cat1        reviews            23

最后我想把数据帧作为原始数据帧。

skunumber   category    rating  reviews
123          Cat1         1       20
124          cat1         2        23

我尝试使用pivot选项执行此操作,如果我们有一个索引列,但这里有2列,则此方法有效。

示例代码:

messy = pd.DataFrame({'row' : ['A', 'B', 'C'], 
                  'a' : [1, 2, 3],
                  'b' : [4, 5, 6],
                  'c' : [7, 8, 9]})

tidy = pd.melt(messy, id_vars='row',     var_name='dimension',value_name='length')  

messy1 = tidy.pivot(index='row',columns='dimension',values='length')   

messy1.reset_index(inplace=True)
messy1.columns.name = '' 

在我的情况下,我试图将索引作为['skunumber','category']传递它不起作用

由于

2 个答案:

答案 0 :(得分:1)

我认为您需要在melt中为参数id_vars添加另一列:

df = df.rename(columns={'overallrating':'rating'})
tidy = pd.melt(df, 
               id_vars=['skunumber','category'],  
               var_name='dimension',
               value_name='length')  
tidy = tidy.drop_duplicates()
print (tidy)
   skunumber category dimension  length
0        123     Cat1    rating       1
1        124     cat1    rating       2
4        123     Cat1   reviews      20
5        124     cat1   reviews      23

messy1 = tidy.set_index(['skunumber','category','dimension'])
             .length
             .unstack()
             .reset_index()

messy1.columns.name = None
print (messy1)
   skunumber category  rating  reviews
0        123     Cat1       1       20
1        124     cat1       2       23

使用stackdrop_duplicates(默认情况下仅保留first值)和最后unstack的另一种简化解决方案:

df = df.rename(columns={'overallrating':'rating'})
tidy = df.set_index(['skunumber','category'])
         .stack()
         .drop_duplicates()
         .unstack()
         .reset_index()

print (tidy)
   skunumber category  rating  reviews
0        123     Cat1       1       20
1        124     cat1       2       23

如果使用真实数据,您可以轻松获得:

  

ValueError:索引包含重复的条目,无法重塑

然后解决方案是下面或另一个答案:

df = pd.DataFrame({'category': ['Cat1', 'Cat1', 'cat1'],
                   'overallrating': [1, 5, 3], 
                   'skunumber': [123, 123, 124], 
                   'reviews': [20, 30, 23], 
                   'rating': [4, 2, 2]})

print (df)
  category  overallrating  rating  reviews  skunumber
0     Cat1              1       4       20        123
1     Cat1              5       2       30        123
2     cat1              3       2       23        124

Nedd groupby按列创建新的index reset_index(此处为skunumbercategory)并汇总某些功能,如meansummaxminfirst ...

df = df.rename(columns={'overallrating':'rating'})
tidy = df.groupby(['skunumber','category'])['rating'].max().unstack().reset_index()
print (tidy)
   skunumber category  rating  rating
0        123     Cat1       5       4
1        124     cat1       3       2

通过评论编辑:

如果重复项需要一些汇总函数,例如maxfirstsummeangroupby

print (df)
   skunumber category  overallrating  rating  reviews  color colorShade
0        123     Cat1              1       1       12  White        Red
1        123     Cat1              1       4       20   Pink      Green
2        124     cat1              2       2       23  Black       Blue

df = df.rename(columns={'overallrating':'rating', 'colorShade':'color'})
g = df.groupby(['skunumber','category'])

tidy1 = g['rating'].max().unstack()
print (tidy1)
                    rating  rating
skunumber category                
123       Cat1           1       4
124       cat1           2       2

tidy2 = g['color'].first().unstack()
print (tidy2)
                    color color
skunumber category             
123       Cat1      White   Red
124       cat1      Black  Blue

然后将concat数据放在一起:

df = pd.concat([tidy1, tidy2],axis=1).reset_index()
print (df)
   skunumber category  rating  rating  color color
0        123     Cat1       1       4  White   Red
1        124     cat1       2       2  Black  Blue

pd.lreshape的另一种解决方案:

tidy = pd.lreshape(df, {'rating':['rating','overallrating'], 'color':['color','colorShade']})
print (tidy)
  category  reviews  skunumber  color  rating
0     Cat1        1        123  White       1
1     Cat1       20        123   Pink       4
2     cat1       23        124  Black       2
3     Cat1        1        123    Red       1
4     Cat1       20        123  Green       1
5     cat1       23        124   Blue       2

tidy = tidy.drop_duplicates(['category','skunumber'])
print (tidy)
  category  reviews  skunumber  color  rating
0     Cat1        1        123  White       1
2     cat1       23        124  Black       2

答案 1 :(得分:1)

您需要pivot_table来集成多个对象,因为它是index参数。但是,请注意,如果存在与这些索引集相对应的重复值,则它们的聚合将产生默认值(aggfunc=np.mean)的平均值。如果您想要对这些值求和,则需要通过提供aggfunc=np.sum来专门执行此操作。

piv_df = df.pivot_table(index=['skunumber', 'category'], columns=['attribute'], values=['attributeRawValue'])
piv_df.columns = piv_df.columns.droplevel(0)
piv_df.reset_index().rename_axis(None, 1)

enter image description here

获取df

data = StringIO(
'''
skunumber   category    overallrating   rating  reviews
123          Cat1          1             1        20
124          cat1          2             2        23
''')

df = pd.read_csv(data, delim_whitespace=True)
df = pd.melt(df, id_vars=['skunumber', 'category'], 
             var_name='attribute', value_name='attributeRawValue')
df.loc[df['attribute']=='overallrating', 'attribute'] = 'rating'
df.drop_duplicates()

enter image description here