Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按函数进行聚合_Python_Pandas_Dataframe - Fatal编程技术网

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等)