在整个数据框列上有效地应用一个函数
Efficiently applying a function on whole dataframe column
我想对这个数据框的列应用一个函数:
df = pd.DataFrame({"a":[0,1,2,3,4,5,6], "b": [10,100,100,100,100,1000,1]})
def scale(values):
scaled_values = (values - np.min(values)) / (np.max(values) - np.min(values))
return scaled_values / np.sum(scaled_values)
此函数需要同时考虑列中的所有值。因此,我无法使用 pandas 的“应用”方法应用该功能。因此目前我只是打电话给
df.loc[:,"a"] = scale(df["a"])
df.loc[:,"b"] = scale(df["b"])
但是,如果我有很多列,我不想这样做,而且遍历这些列也很丑陋:
for c in df.columns:
df.loc[:,c] = scale(df[c])
我想知道是否有一种 pandas 方法可以立即将一种方法“应用”到整个列,这样我就可以摆脱这个丑陋的循环。有什么建议吗?
是的,它调用了DataFrame.apply
来处理每一列的函数:
#default axis=0
df = df.apply(scale)
#df = df.apply(scale, axis=0)
print (df)
a b
0 0.000000 0.006410
1 0.047619 0.070513
2 0.095238 0.070513
3 0.142857 0.070513
4 0.190476 0.070513
5 0.238095 0.711538
6 0.285714 0.000000
这里可以将所有列一起传递 - 这样性能会更好:
df = scale(df)
#alternative
df = df.pipe(scale)
print (df)
a b
0 0.000000 0.006410
1 0.047619 0.070513
2 0.095238 0.070513
3 0.142857 0.070513
4 0.190476 0.070513
5 0.238095 0.711538
6 0.285714 0.000000
性能:
#[70000 rows x 20 columns]
df = pd.concat([df] * 10000, ignore_index=True)
df = pd.concat([df] * 10, axis=1, ignore_index=True)
In [72]: %timeit df.apply(scale)
57.3 ms ± 3.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [73]: %timeit df.pipe(scale)
38.5 ms ± 241 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [74]: %timeit scale(df)
38.6 ms ± 780 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
我想对这个数据框的列应用一个函数:
df = pd.DataFrame({"a":[0,1,2,3,4,5,6], "b": [10,100,100,100,100,1000,1]})
def scale(values):
scaled_values = (values - np.min(values)) / (np.max(values) - np.min(values))
return scaled_values / np.sum(scaled_values)
此函数需要同时考虑列中的所有值。因此,我无法使用 pandas 的“应用”方法应用该功能。因此目前我只是打电话给
df.loc[:,"a"] = scale(df["a"])
df.loc[:,"b"] = scale(df["b"])
但是,如果我有很多列,我不想这样做,而且遍历这些列也很丑陋:
for c in df.columns:
df.loc[:,c] = scale(df[c])
我想知道是否有一种 pandas 方法可以立即将一种方法“应用”到整个列,这样我就可以摆脱这个丑陋的循环。有什么建议吗?
是的,它调用了DataFrame.apply
来处理每一列的函数:
#default axis=0
df = df.apply(scale)
#df = df.apply(scale, axis=0)
print (df)
a b
0 0.000000 0.006410
1 0.047619 0.070513
2 0.095238 0.070513
3 0.142857 0.070513
4 0.190476 0.070513
5 0.238095 0.711538
6 0.285714 0.000000
这里可以将所有列一起传递 - 这样性能会更好:
df = scale(df)
#alternative
df = df.pipe(scale)
print (df)
a b
0 0.000000 0.006410
1 0.047619 0.070513
2 0.095238 0.070513
3 0.142857 0.070513
4 0.190476 0.070513
5 0.238095 0.711538
6 0.285714 0.000000
性能:
#[70000 rows x 20 columns]
df = pd.concat([df] * 10000, ignore_index=True)
df = pd.concat([df] * 10, axis=1, ignore_index=True)
In [72]: %timeit df.apply(scale)
57.3 ms ± 3.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [73]: %timeit df.pipe(scale)
38.5 ms ± 241 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [74]: %timeit scale(df)
38.6 ms ± 780 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)