更新 pandas 数据框的最快方法(具有复杂条件的元素的部分总和)
The fastest way to update (partial sum of elements with complex conditions) the pandas dataframe
我尝试更新具有 300 万行的 pandas 数据框。在下面,我将我的问题简化为一个更简单的问题。简而言之,它确实在累积意义上增加了价值。
但是,这个功能对我来说花费的时间太长了,像一个真正的问题需要 10 多个小时。有提速的空间吗?我应该只在最后更新吗?
我们可以用比 iterrows() 更快的方式更新 pandas 数据框吗?
我们能否通过索引 select 多行然后更新?
def set_r(group, i, colname, add):
if colname in group:
prev = group.iloc[i][colname]
if math.isnan(prev):
group.set_value(i, colname, add)
else:
group.set_value(i, colname, prev+add)
else:
group.set_value(i, colname, add)
def set_bl_info(group, i, r, bl_value, timeframe, clorca, bl_criteria):
group.set_value(i, timeframe + '_' + bl_criteria, True)
colname = timeframe + '_' + clorca + '_' + 'bb_count_'+ bl_criteria
set_r(group, i, colname, 1)
def bl_assign(days, bl_key, bl_value, group, bl_p05, bl_p01):
print bl_key
sub_group = group[(group.pledged_date >= bl_value[0]) & (group.pledged_date <= bl_value[1])]
coexisting_icl = sub_group[(sub_group.project_category == bl_value[2]) & (sub_group.cluster == bl_value[3])]
for i, r in coexisting_icl.iterrows():
set_bl_info(group, i, r, bl_value, 'coexisting', 'icl','p1')
# main function
bl_assign(days, bl_key, bl_value, group, bl_p05, bl_p01)
为简单起见,我的问题如下所示:
A B C
0 0 0 False
1 7 0 True
2 8 0 True
3 5 0 True
如果 C 与 A 列的元素之和为真,则更新 B 列
A B C
0 0 0 False
1 7 20 True
2 8 20 True
3 5 20 True
之后,如果D也为真则用E的总和累加更新B
A B C D E
0 0 0 False False 1
1 7 20 True False 1
2 8 20 True True 1
3 5 20 True True 1
A B C D E
0 0 0 False False 1
1 7 20 True False 1
2 8 22 True True 1
3 5 22 True True 1
Update B column if C is true with sum of A column's elements
import numpy as np
df['B'] = np.where(df.C, df.A.sum(), 0)
After then, if D is also tru then update B with the sum of E (using the comment to the question above)
df.B = df.B + np.where(df.D, (df.E * df.D.astype(int)).sum(), 0)
所以,最后你有
>>> df
A C B E D
0 0 False 0 1 False
1 7 True 20 1 False
2 8 True 22 1 True
3 5 True 22 1 True
我尝试更新具有 300 万行的 pandas 数据框。在下面,我将我的问题简化为一个更简单的问题。简而言之,它确实在累积意义上增加了价值。
但是,这个功能对我来说花费的时间太长了,像一个真正的问题需要 10 多个小时。有提速的空间吗?我应该只在最后更新吗?
我们可以用比 iterrows() 更快的方式更新 pandas 数据框吗?
我们能否通过索引 select 多行然后更新?
def set_r(group, i, colname, add):
if colname in group:
prev = group.iloc[i][colname]
if math.isnan(prev):
group.set_value(i, colname, add)
else:
group.set_value(i, colname, prev+add)
else:
group.set_value(i, colname, add)
def set_bl_info(group, i, r, bl_value, timeframe, clorca, bl_criteria):
group.set_value(i, timeframe + '_' + bl_criteria, True)
colname = timeframe + '_' + clorca + '_' + 'bb_count_'+ bl_criteria
set_r(group, i, colname, 1)
def bl_assign(days, bl_key, bl_value, group, bl_p05, bl_p01):
print bl_key
sub_group = group[(group.pledged_date >= bl_value[0]) & (group.pledged_date <= bl_value[1])]
coexisting_icl = sub_group[(sub_group.project_category == bl_value[2]) & (sub_group.cluster == bl_value[3])]
for i, r in coexisting_icl.iterrows():
set_bl_info(group, i, r, bl_value, 'coexisting', 'icl','p1')
# main function
bl_assign(days, bl_key, bl_value, group, bl_p05, bl_p01)
为简单起见,我的问题如下所示:
A B C
0 0 0 False
1 7 0 True
2 8 0 True
3 5 0 True
如果 C 与 A 列的元素之和为真,则更新 B 列
A B C
0 0 0 False
1 7 20 True
2 8 20 True
3 5 20 True
之后,如果D也为真则用E的总和累加更新B
A B C D E
0 0 0 False False 1
1 7 20 True False 1
2 8 20 True True 1
3 5 20 True True 1
A B C D E
0 0 0 False False 1
1 7 20 True False 1
2 8 22 True True 1
3 5 22 True True 1
Update B column if C is true with sum of A column's elements
import numpy as np
df['B'] = np.where(df.C, df.A.sum(), 0)
After then, if D is also tru then update B with the sum of E (using the comment to the question above)
df.B = df.B + np.where(df.D, (df.E * df.D.astype(int)).sum(), 0)
所以,最后你有
>>> df
A C B E D
0 0 False 0 1 False
1 7 True 20 1 False
2 8 True 22 1 True
3 5 True 22 1 True