在你的情况下你可以这样做:
df.loc[mask, ['P1I', 'P2I', 'P3I']] -= c_offset
如果需要,您还可以对每列使用不同的偏移量,如下所示(就性能而言,它看起来与第一个非常相似):
df.loc[mask, ['P1I', 'P2I', 'P3I']] -= [ c_offset_1, c_offset_2, c_offset_3 ]
但是,如果性能至关重要,那么最好的选择似乎确实是使用 numpy 格式。可能如果您的“数学争论”大于单个减法,这似乎是要走的路:
df.loc[ mask, ["P1I", "P2I", "P3I"]] = df.loc[ mask, ["P1I", "P2I", "P3I"]].values - c_offset
注意:OP 在他/她的数据集中测试了这种方法,并提到它实际上比仅使用前一种方法要慢。试图复制这个,但我的电脑在我能够复制之前几乎崩溃了......
我比较了不同方法的一些时间安排:
import pandas as pd
import numpy as np
df = pd.DataFrame({ "P1I": np.random.rand(1000000),
"P2I": np.random.rand(1000000),
"P3I": np.random.rand(1000000) })
c_th = 0.5
c_offset = -1
mask = df.P2I > c_th
%timeit df.loc[ mask, "P1I" ] = df.loc[ mask , "P1I" ] - c_offset; df.loc[ mask, "P2I" ] = df.loc[ mask , "P2I" ] - c_offset; df.loc[ mask, "P3I" ] = df.loc[ mask , "P3I" ] - c_offset
# 77.9 ms ± 1.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit df.loc[ mask, ["P1I", "P2I", "P3I"]] -= c_offset
# 59.3 ms ± 1.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit df.loc[ mask, ["P1I", "P2I", "P3I"]] -= [ c_offset, c_offset, c_offset ]
# 59.5 ms ± 3.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit df.loc[ mask, ["P1I", "P2I", "P3I"]] = df.loc[ mask, ["P1I", "P2I", "P3I"]].values - c_offset
# 43.6 ms ± 553 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)