Pandas apply与lambda函数的效率

0 投票
1 回答
2108 浏览
提问于 2025-04-18 13:54

我有一个数据框,里面有一些数据。

data = 
     a     b     c    val
0   'a1'  'b1'  'c1'   5
1   'a1'  'b1'  'c2'   10
2   'a1'  'b2'  'c3'   1 
3   'a2'  'b1'  'c4'   30
4   'a2'  'b1'  'c5'   20
5   'a2'  'b1'  'c6'   10

我想创建一个新的数据框,列和原来的数据框一样。这个新数据框里的某个值(a, b, c)应该等于所有(aa, bb, cc)值的总和,前提是a等于aa,b等于bb,并且(aa, bb, cc)的值要大于等于(a, b, c)的值。这里的aa其实是a的别名,其他的也是一样。

我想要的结果是:

data_new = 
     a     b     c    val
0   'a1'  'b1'  'c1'   15
1   'a1'  'b1'  'c2'   10
2   'a1'  'b2'  'c3'   1 
3   'a2'  'b1'  'c4'   30
4   'a2'  'b1'  'c5'   50
5   'a2'  'b1'  'c6'   60

然后我做了以下操作:

data['key'] = data['a']+data['b']
data_new = data
data_new = data.apply(lambda row: data[ (data.key==row.key) 
                                      & (data.val>=row.val) ].val.sum(), axis=1)
del data_new['key']

实际上,在我的真实数据中,还有更多像a和b这样的列,所以用布尔比较的方法,比如:

(data.a==row.a) & (data.a==row.b) & ...

会比较慢。问题是,即使现在的做法也没有我想要的那么快。我有很大的表格数据。有没有什么方法可以更快、更有效地做到这一点?

1 个回答

2

如果我理解你的意思,你可以用 cumsum 这个函数,稍微加点排序就行:

>>> grouped = df.sort("val", ascending=False).groupby(["a", "b"])
>>> df["new_val"] = grouped["val"].cumsum()
>>> df
    a   b   c  val  new_val
0  a1  b1  c1    5       15
1  a1  b1  c2   10       10
2  a1  b2  c3    1        1
3  a2  b1  c4   30       30
4  a2  b1  c5   20       50
5  a2  b1  c6   10       60

因为你想把那些大于等于你关注的值的数加在一起,你可以先把这些值按从大到小的顺序放在 A、B 组里,然后再对这些值进行累加。

撰写回答