计数,平均和连接Pandas Dataframe

时间:2017-03-09 11:59:12

标签: python pandas dataframe aggregate

我在Pandas中有一个数据框,其中包含一组产品评论,适用于与选择的评论网站略有不同的产品。每次审核都与产品相关,并带有数字分数。评论还有一个文本字段,其中包含每个评论的文本(相当长的字段),以及从中获取的源站点的名称。 E.g。

product    score    source    text
------------------------------------------
K3         4.0      site1     long-text
P2         2.0      site7     text
K3         3.0      site2     paragraph
i7         1.0      site4     review-text
P2         5.0      site2     more-text
K3         4.0      site5     texts-on-text

我想将每个产品组合在一个新表中,以便我可以分析每个产品的审核方式。我最终会进行文本分析(POS标记等),以了解每种产品的评估方式。

我想首先创建一个新的数据框,按照“产品”进行分组。我想计算每个产品在列'计数'中的评论数量。将会有一个列来计算“得分”的平均值。分组时。还将有一个列合并每个产品的文本字段,以便可以作为整体而不是单独分析审阅文本。 E.g。

product    mean_score    count     text_combined
---------------------------------------------------
K3         3.66          3         long-text, paragraph, texts-on-text
P2         3.5           2         text, more-text
i7         1.0           1         review-text

来源'在此特定分析中不需要该列,但我已将其包含在内,以表明数据框中还有其他列。

由此我可以更轻松地分解每个产品的文本,而不是单独的评论。

先谢谢Stack!

1 个答案:

答案 0 :(得分:5)

您可以groupby使用agg

df = df.groupby('product').agg({'score':'mean', 'source':'size', 'text': ', '.join})
#change order of columns, create column from index values 
df = df.reindex_axis(['score','source','text'], axis=1).reset_index()
#set new column names
df.columns = ['product','mean_score','count','text_combined']
print (df)
  product  mean_score  count                        text_combined
0      K3    3.666667      3  long-text, paragraph, texts-on-text
1      P2    3.500000      2                      text, more-text
2      i7    1.000000      1                          review-text

编辑:

输出中dict的解决方案:

from collections import Counter

df = df.groupby('product')
       .agg({'score':'mean', 'product':'size', 'text': ', '.join, 'source': lambda x: [dict(Counter(x))]})
#change order of columns, create column from index values 
df = df.reindex_axis(['score','product','text', 'source'], axis=1)
       .rename_axis('a')
       .reset_index()
#set new column names
df.columns = ['product','mean_score','count','text_combined', 'count_sources']
df['L'] = pd.Series(df.values.tolist())
print (df)
  product  mean_score  count                        text_combined  \
0      K3    3.666667      3  long-text, paragraph, texts-on-text   
1      P2    3.500000      2                      text, more-text   
2      i7    1.000000      1                          review-text   

                            count_sources  \
0  [{'site1': 1, 'site2': 1, 'site5': 1}]   
1              [{'site7': 1, 'site2': 1}]   
2                          [{'site4': 1}]   

                                                   L  
0  [K3, 3.6666666666666665, 3, long-text, paragra...  
1  [P2, 3.5, 2, text, more-text, [{'site7': 1, 's...  
2          [i7, 1.0, 1, review-text, [{'site4': 1}]]  

输出中带有tuples的解决方案:

from collections import Counter

df = df.groupby('product')
       .agg({'score':'mean', 'product':'size', 'text': ', '.join, 'source': lambda x: list(dict(Counter(x)).items())})
#change order of columns, create column from index values 
df = df.reindex_axis(['score','product','text', 'source'], axis=1)
       .rename_axis('a')
       .reset_index()

#set new column names
df.columns = ['product','mean_score','count','text_combined', 'count_sources']
df['L'] = pd.Series(df.values.tolist())
print (df)
  product  mean_score  count                        text_combined  \
0      K3    3.666667      3  long-text, paragraph, texts-on-text   
1      P2    3.500000      2                      text, more-text   
2      i7    1.000000      1                          review-text   

                          count_sources  \
0  [(site1, 1), (site2, 1), (site5, 1)]   
1              [(site7, 1), (site2, 1)]   
2                          [(site4, 1)]   

                                                   L  
0  [K3, 3.6666666666666665, 3, long-text, paragra...  
1  [P2, 3.5, 2, text, more-text, [(site7, 1), (si...  
2            [i7, 1.0, 1, review-text, [(site4, 1)]]