Python 按函数进行聚合
我有如下数据:Python 按函数进行聚合,python,pandas,dataframe,Python,Pandas,Dataframe,我有如下数据: id movie details value 5 cane1 good 6 5 wind2 ok 30.3 5 wind1 ok 18 5 cane1 good 2 5 cane22 ok 4 5 cane34 good 7 5 wind2 ok 2 我希望输出符合以下条件: 如果电影名称以“cane”开头-求和值 如果电影名称以“风”开头,则计算发生次数 因此,最终输出将为: id movi
id movie details value
5 cane1 good 6
5 wind2 ok 30.3
5 wind1 ok 18
5 cane1 good 2
5 cane22 ok 4
5 cane34 good 7
5 wind2 ok 2
我希望输出符合以下条件:
如果电影名称以“cane”开头-求和值
如果电影名称以“风”开头,则计算发生次数
因此,最终输出将为:
id movie value
5 cane1 8
5 cane22 4
5 cane34 7
5 wind1 1
5 wind2 2
我尝试使用:
movie_df.groupby(['id']).apply(aggr)
def aggr(x):
if x['movie'].str.startswith('cane'):
y = x.groupby(['value']).sum()
else:
y = x.groupby(['movie']).count()
return y
但它不起作用。有人能帮忙吗?首先,您需要执行字符串操作。我猜在你的情况下,你不希望电影名字中有数字。使用上讨论的解决方案。 然后对新系列调用groupby()
仅供参考:一些电影名称只有数字;在这种情况下,您需要使用update函数 在可能的情况下,您应该以矢量化操作为目标 您可以计算两个结果,然后将它们连接起来
mask = df['movie'].str.startswith('cane')
df1 = df[mask].groupby('movie')['value'].sum()
df2 = df[~mask].groupby('movie').size()
res = pd.concat([df1, df2], ignore_index=0)\
.rename('value').reset_index()
print(res)
movie value
0 cane1 8.0
1 cane22 4.0
2 cane34 7.0
3 wind1 1.0
4 wind2 2.0
这可能有多种方法。一种方法是先按电影名称的开头进行过滤,然后进行聚合和合并
cane = movie_df[movie_df['movie'].str.startswith('cane1')]
wind = movie_df[movie_df['movie'].str.startswith('wind')]
cane_sum = cane.groupby(['id']).agg({'movie':'first', 'value':'sum'}).reset_index()
wind_count = wind.groupby(['id']).agg({'movie':'first', 'value':'count'}).reset_index()
pd.concat([cane_sum, wind_count])
首先,我将创建一个列来定义所需的组。对于手头的示例,可以使用
df['group']=df.movie.transform(lambda x:x[:4])
下一步是按此列分组
df.groupby('group').apply(agg_fun)
使用以下聚合函数
def agg_fun(grp):
if grp.name == "cane":
value=grp.value.sum()
else:
value=grp.value.count()
return value
这段代码的输出是
group
cane 19.0
wind 3.0
我看到
cane
的值为19,即6+2+4+7。感谢您的回复!然而,我意识到在我最初的问题中,我没有正确地提供输出。我对这个问题稍加修改。你能看一下吗?基本上,我需要输出的所有电影(即:cane1、cane22、cane34、wind1、wind2等),谢谢!现在我只需要id列,因为我还必须根据id进行分组。非常感谢!您尚未确定问题中id
的逻辑。请使用groupby(['id','movie'])
或使用@Retiefasaurus'答案中的first
。谢谢您的回复!然而,我意识到在我最初的问题中,我没有正确地提供输出。我对这个问题稍加修改。你能看一下吗?基本上,我需要输出的所有电影(即:cane1、cane22、cane34、wind1、wind2等)