2016-12-14 128 views
0

我有一个数据框如下,我想保留在这里最好的评级列之一。如何解开大熊猫数据框

原始数据帧:

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

的,我都快融化然后数据帧和重命名overallrating来评价。最后删除重复,如果有的话,我想再转换融化的数据帧原始格式。

融化的数据框看起来像这样:

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 

数据帧貌似overallrating到评级和删除重复的重命名后。

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 

我试着用旋转选项执行此,这个工程如果我们有一个索引列,但在这里我有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', '分类']没有工作

感谢

回答

1

我想你需要另一列添加到参数id_varsmelt

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 

stack另一个simplier解决方案,drop_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: Index contains duplicate entries, cannot reshape

然后解决方案是波纹管或其他回答:

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按列创建新在reset_index之前的(这里是skunumbercategory)并且集合了一些功能,如mean,sum,max,min,first ...

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 
+0

感谢Jezrael,您的解决方案在我的样本数据的工作。我会尝试使用实际的数据。 –

+0

Jezrael,我试着用我得到的实际数据**“ValueError:Index包含重复条目,无法重新设置”**错误。 –

+0

也试图使用你给出的解决方案,但我有更多的列和哪些也是字符串列。 –

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

+0

解决方案与重复的工作也,只有我认为是重要的关于默认集合函数'平均'通知。 – jezrael

+0

@jezrael,好赶上!我已经添加了一个小笔记到我的文章 –

+0

尼基,我试图使用 –