我正在寻找一种更高效和可维护的方式来按组有条件地偏移值。最容易展示一个例子。
当Offset == False
时,值始终为非负数;当Offset == True
时,值始终为负数。我希望通过Label将正值(向下取整到0)与负值“折叠”起来。
注意,Label
+ Offset
组合始终是唯一的。由于Offset
是布尔值,每个Label最多只能有2行。
示例1:
df = pd.DataFrame({'Label': ['L1', 'L2', 'L3', 'L3'],
'Offset': [False, False, False, True],
'Value': [100, 100, 50, -100]})
# input
# Label Offset Value
# 0 L1 False 100
# 1 L2 False 100
# 2 L3 False 50
# 3 L3 True -100
期望的输出:
Label Offset Value
0 L1 False 100
1 L2 False 100
2 L3 False 0
3 L3 True -50
示例2
df = pd.DataFrame({'Label': ['L1', 'L2', 'L3', 'L3'],
'Offset': [False, False, False, True],
'Value': [100, 100, 100, -50]})
# input
# Label Offset Value
# 0 L1 False 100
# 1 L2 False 100
# 2 L3 False 100
# 3 L3 True -50
期望的输出结果:
Label Offset Value
0 L1 False 100
1 L2 False 100
2 L3 False 50
3 L3 True 0
当前低效的解决方案
我的当前解决方案是手动循环,速度慢且难以维护:
for label in df['Label'].unique():
mask = df['Label'] == label
if len(df.loc[mask]) == 2:
val_false = df.loc[~df['Offset'] & mask, 'Value'].iloc[0]
val_true = df.loc[df['Offset'] & mask, 'Value'].iloc[0]
if val_false > abs(val_true):
df.loc[~df['Offset'] & mask, 'Value'] += val_true
df.loc[df['Offset'] & mask, 'Value'] = 0
else:
df.loc[~df['Offset'] & mask, 'Value'] = 0
df.loc[df['Offset'] & mask, 'Value'] += val_false
我正在寻找一种矢量化,或至少部分矢量化的解决方案来提高性能并摆脱混乱。
Label
+Offset
组合始终是唯一的。由于Offset
是布尔值,因此每个标签最多只能有2行。 - jpp