在 Pandas 中如何使用带有 HAVING 子句的 GROUP_CONCAT?

huangapple go评论71阅读模式
英文:

How to use GROUP_CONCAT with HAVING clause in Pandas?

问题

你可以使用Pandas来实现与上述SQL查询相同的结果,代码如下:

import pandas as pd

# 创建DataFrame
data = {'name': ['John', 'Joe', 'Joe', 'Marcus', 'John', 'John'],
        'type': [1, 0, 1, 0, 2, 0]}
df = pd.DataFrame(data)

# 使用groupby、agg和join来获取结果
result = df.groupby('name')['type'].agg(lambda x: ','.join(x.astype(str)) if len(x) > 1 else x.astype(str)).reset_index()

# 将列名改为小写
result.columns = result.columns.str.lower()

result

这段代码会产生一个Pandas DataFrame,其中'name'列是分组的名称,'type'列包含相应的组合值,只有在每个分组中有多个值时才会进行组合。

英文:

Suppose I have a dataframe like this:

name type
John 1
Joe 0
Joe 1
Marcus 0
John 2
John 0

How can I use Pandas to have the same result as:

SELECT name, GROUP_CONCAT(type)
FROM df
GROUP BY name
HAVING COUNT(*)>1;
name type
john 0,1,2
joe 0,1

答案1

得分: 2

你可以使用自定义的 groupby.agg 来实现,类似以下方式:

out = (df
   .groupby('name', as_index=False, sort=False)['type']
   .agg(lambda s: ','.join(s.sort_values().astype(str)) if len(s) > 1 else None)
   .dropna(subset='type')
)

或者:

out = (df
   .groupby('name', as_index=False, sort=False)
   .agg({'type': ('type', lambda s: ','.join(s.sort_values().astype(str))),
         'count': ('type', 'count')
        })
   .loc[lambda d: d.pop('count').gt(1)]
)

或者:

out = (df
   .groupby('name', as_index=False, sort=False)['type']
   .agg(lambda s: ','.join(s.sort_values().astype(str)))
   .loc[lambda d: d['type'].str.contains(',')]
)

输出结果:

   name   type
0  John  0,1,2
1   Joe    0,1
英文:

You can use a custom groupby.agg with something like:

out = (df
   .groupby('name', as_index=False, sort=False)['type']
   .agg(lambda s: ','.join(s.sort_values().astype(str)) if len(s)>1 else None)
   .dropna(subset='type')
)

Or:

out = (df
   .groupby('name', as_index=False, sort=False)
   .agg(**{'type': ('type', lambda s: ','.join(s.sort_values().astype(str))),
           'count': ('type', 'count')
          })
   .loc[lambda d: d.pop('count').gt(1)]
)

Or:

out = (df
   .groupby('name', as_index=False, sort=False)['type']
   .agg(lambda s: ','.join(s.sort_values().astype(str)))
   .loc[lambda d: d['type'].str.contains(',')]
)

Output:

   name   type
0  John  0,1,2
1   Joe    0,1

答案2

得分: 2

你可以尝试以下操作:

out = (df[df.duplicated('name', keep=False)].astype({'type': str}).sort_values('type')
          .groupby('name', sort=False, as_index=False)['type'].agg(','.join))
print(out)

# 输出结果
   name   type
0   Joe    0,1
1  John  0,1,2

注意:我已经将代码部分保持不变,只翻译了注释和输出结果。

英文:

You can probably do:

out = (df[df.duplicated('name', keep=False)].astype({'type': str}).sort_values('type')
          .groupby('name', sort=False, as_index=False)['type'].agg(','.join))
print(out)

# Output
   name   type
0   Joe    0,1
1  John  0,1,2

huangapple
  • 本文由 发表于 2023年5月24日 22:19:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76324555.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定