我有这个数据框:
df = {user: ['a', 'a','b','b', 'c', 'd', 'a', 'c', 'b'],
otherData:['bnd', 'smd','rtf','ldf', 'gfd', 'egq', 'wqd, 'lvm', 'zrb'],
grades: [12, 9, 7, 11, 7, 9, 5, 8, 1]
}
对于每个用户,我想计算“最低成绩+下一年级之间的差异”的平均值。 例如用户a的等级是5、9、12。我想要(5+4+3)/3 = 4
最后,对于这个例子,我想要这个结果:
用户 | 资源 |
---|---|
一 | 4 |
b | 3.666 |
c | 4 |
d | 9 |
我更喜欢使用 pandas 或 numpy 的方法和函数来解决它。
答案 0 :(得分:3)
为了提高性能,首先对每组的值进行排序(按两列),然后得到差异,用第一个值(最小)替换第一个缺失值并得到 mean
:
f = lambda x: x.diff().fillna(x).mean()
#numpy alternative
#f = lambda x: np.mean(np.append(np.diff(x),x.iat[0]))
df2 = df.sort_values(['user','grades']).groupby('user')['grades'].agg(f).reset_index(name='res')
print (df2)
user res
0 a 4.000000
1 b 3.666667
2 c 4.000000
3 d 9.000000
替代方案:
df = df.sort_values(['user','grades'])
df['res'] = df.groupby('user')['grades'].diff().fillna(df['grades'])
print (df)
user otherData grades res
6 a wqd 5 5.0
1 a smd 9 4.0
0 a bnd 12 3.0
8 b zrb 1 1.0
2 b rtf 7 6.0
3 b ldf 11 4.0
4 c gfd 7 7.0
7 c lvm 8 1.0
5 d egq 9 9.0
df2 = df.groupby('user', as_index=False)['res'].mean()
print (df2)
user res
0 a 4.000000
1 b 3.666667
2 c 4.000000
3 d 9.000000
RandomGuy 评论的解决方案是最快的:
<块引用>如果用户 a 对成绩 x,y,z 进行了排序;那么你想输出 (x + (y-x) + (z-y))/3。但这恰好等于 z / 3,因为 x 和 y 会自行简化!因此,您只需要将每个用户的最大成绩除以他的成绩数即可。
所以这意味着需要使用 max
和 GroupBy.count
进行聚合以排除可能的缺失值,然后进行除法:
df1 = df.groupby('user')['grades'].agg(['max','count'])
print (df1)
max size
user
a 12 3
b 11 3
c 8 2
d 9 1
df2 = df1['max'].div(df1['count']).reset_index(name='res')
print (df2)
user res
0 a 4.000000
1 b 3.666667
2 c 4.000000
3 d 9.000000
答案 1 :(得分:1)
试试:
x = df.groupby('user')['grades'].apply(lambda x: (x.sort_values().diff().sum() + x.min())/len(x)).reset_index(name="res")
print(x)
打印:
user res
0 a 4.000000
1 b 3.666667
2 c 4.000000
3 d 9.000000