Skip to main content
 首页 » 编程设计

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

2025年02月15日22itcoder

我有一个看起来像这样的表:

当前数据帧/表:'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'. 

任何人都可以帮我做一个简单的黑客吗?

请您参考如下方法:

使用 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 

如有必要, NaN s 可以用空字符串替换 - 在第一个 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