jpp*_*jpp 7 python performance dataframe pandas pandas-groupby
我正在寻找一种更有效和可维护的方法来有条件地按组抵消价值.最容易展示一个例子.
值始终为非负值Offset == False且始终为负值Offset == True.我要做的是通过Label"折叠"正值(地板为0)和负值.
Note Label+ Offsetcombined总是唯一的.由于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
Run Code Online (Sandbox Code Playgroud)
期望的输出:
Label Offset Value
0 L1 False 100
1 L2 False 100
2 L3 False 0
3 L3 True -50
Run Code Online (Sandbox Code Playgroud)
例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
Run Code Online (Sandbox Code Playgroud)
期望的输出:
Label Offset Value
0 L1 False 100
1 L2 False 100
2 L3 False 50
3 L3 True 0
Run Code Online (Sandbox Code Playgroud)
当前效率低下的解决方
我目前的解决方案是手动循环,速度慢且难以维护:
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
Run Code Online (Sandbox Code Playgroud)
我正在寻找一个矢量化或至少部分矢量化的解决方案,以提高性能并摆脱这种混乱.
也许:
label_sums = df.Value.groupby(df.Label).transform(sum)
df["new_sum"] = label_sums.where(np.sign(label_sums) == np.sign(df.Value), 0)
Run Code Online (Sandbox Code Playgroud)
这给了我
In [42]: df
Out[42]:
Label Offset Value new_sum
0 L1 False 100 100
1 L2 False 100 100
2 L3 False 50 0
3 L3 True -100 -50
4 L4 False 100 100
5 L5 False 100 100
6 L6 False 100 50
7 L6 True -50 0
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
211 次 |
| 最近记录: |