Pandas/iPython 笔记本(Jupyter)中 DataFrame/table 中的 GROUP BY 行?

Posted

技术标签:

【中文标题】Pandas/iPython 笔记本(Jupyter)中 DataFrame/table 中的 GROUP BY 行?【英文标题】:GROUP BY rows in DataFrame/table in Pandas/iPython notebook (Jupyter)? 【发布时间】:2017-10-11 07:24:05 【问题描述】:

我有一个如下所示的表格:

当前数据帧/表:'original_table'

   col_1          col_2             col_3
0  Non-Saved      www.google.com    10
1  Non-Saved      www.facebook.com  20
2  Non-Saved      www.linkedin.com  20
3  Saved          www.Quora.com     30
4  Saved          www.gmail.com     40

我可以使用 SQL 查询导出如下表吗?

    col_1          col_2             col_3
 0  Non-Saved      www.google.com    50
                   www.facebook.com
                   www.linkedin.com
 1  Saved          www.Quora.com     70
                   www.gmail.com    

基本上,我希望一个表具有来自 col_1 的 DISTINCT 值、来自 col_2 的所有对应值和来自 col_3 的对应值的 SUM(col_3) 在一行中。

我的查询:

 sql("""SELECT col_1, group_concat(col_2) as col_2, SUM(col_3) as col_3
 FROM original_table
 GROUP BY col_1
 """).show()

我尝试使用 group_concat 使用嵌入式 SQL 查询,但它给了我以下错误:

AnalysisException: u"Undefined function: 'GROUP_CONCAT'. This function 
is neither a registered temporary function nor a permanent function 
registered in the database 'default'.

谁能帮我做一个简单的hack?

【问题讨论】:

【参考方案1】:

使用GroupBy.transform - 它返回与原始组相同大小的Series

#first convert column to numeric
df['col_3'] = df['col_3'].astype(int) #float

df['col_3'] = df.groupby('col_1')['col_3'].transform('sum')
print (df)
       col_1             col_2  col_3
0  Non-Saved    www.google.com     50
1  Non-Saved  www.facebook.com     50
2  Non-Saved  www.linkedin.com     50
3      Saved     www.Quora.com     70
4      Saved     www.gmail.com     70

如果只需要第一个值:

df[['col_1','col_3']] = df[['col_1','col_3']].mask(df['col_1'].duplicated())
print (df)
       col_1             col_2  col_3
0  Non-Saved    www.google.com   50.0
1        NaN  www.facebook.com    NaN
2        NaN  www.linkedin.com    NaN
3      Saved     www.Quora.com   70.0
4        NaN     www.gmail.com    NaN

如有必要,NaNs 可以替换为空字符串 - 在第一个 string 列中没有问题,但在最后一个混合类型 - 带有数字的字符串和某些功能应该失败:

df[['col_1','col_3']] = df[['col_1','col_3']].mask(df['col_1'].duplicated()).fillna('')
print (df)
       col_1             col_2 col_3
0  Non-Saved    www.google.com    50
1             www.facebook.com      
2             www.linkedin.com      
3      Saved     www.Quora.com    70
4                www.gmail.com      

print (df['col_3'].apply(type))
0    <class 'float'>
1      <class 'str'>
2      <class 'str'>
3    <class 'float'>
4      <class 'str'>
Name: col_3, dtype: object

【讨论】:

df['col_3'] = df.groupby('col_1')['col_3'].transform('sum') 给了我:col_1 col_2 col_3 Non-Saved www.google.com 102020 Non-Saved www.facebook.com 102020 Non-Saved www.linkedin.com 102020 Saved www.Quora.com 3040 Saved www.gmail.com 3040 您需要先将第 3 列转换为数字,例如 df['col_3'] = df['col_3'].astype(int) 现在可以了。在这种情况下,是否可以在 2 行中获得结果?谢谢! 如果想要 DataFrame 作为输出然后不,这是不可能的 - 所有列都必须被填充 - 所以如果没有值那么 NaNs。 酷谢谢!我将尝试通过用户定义的函数来完成。我会接受这个答案,这样问题就不会悬而未决。

以上是关于Pandas/iPython 笔记本(Jupyter)中 DataFrame/table 中的 GROUP BY 行?的主要内容,如果未能解决你的问题,请参考以下文章

什么是Jupyter Notebook?

Jupyter 交互式小部件未正确执行

Python自学路第一天:python应用

jupyter怎么输出一首古诗

后台运行jupyter notebook

每周分享第 1 期(2019.4.6)