我有如下数据:
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‘开头-求和值
如果电影名称以'wind‘开头-计算出现的次数。
所以-最终输出将是:
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但它不起作用。有谁能帮帮忙吗?
发布于 2018-08-24 22:38:19
在可能的情况下,你的目标应该是矢量化的操作。
您可以计算2个结果,然后将它们连接起来。
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发布于 2018-08-24 22:55:24
可能有多种方法可以做到这一点。一种方法是首先按电影名称的开头过滤,然后聚合和合并。
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])发布于 2018-08-24 22:26:37
首先,您需要执行字符串操作。我猜在你的情况下,你不想在电影名称中使用数字。使用pandas applying regex to replace values上讨论的解决方案。然后在新序列上调用groupby()。
仅供参考:有些电影名称只有数字,在这种情况下,需要使用update函数。https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.update.html
https://stackoverflow.com/questions/52006414
复制相似问题