对于性能(因为我们正在寻找的效率在这里),我会建议使用broadcasting
一个NumPy
基础的方法 -
a = df.values
N = df.columns.values.astype(int)
df_out = pd.DataFrame((1-(1+a)**-N)/a, columns=df.columns, index=df.index)
样品输入,输出 -
In [41]: df
Out[41]:
1 3
Scenario1 0.001 0.050
Scenario2 0.003 0.010
Scenario3 0.001 0.042
Scenario4 0.090 0.006
Scenario5 0.020 0.040
In [42]: df_out
Out[42]:
1 3
Scenario1 0.999001 2.723248
Scenario2 0.997009 2.940985
Scenario3 0.999001 2.764591
Scenario4 0.917431 2.964357
Scenario5 0.980392 2.775091
与numexpr
模块
在所涉及的计算展望进一步提升,看来我们正在处理power
和division
基础操作。这些可以与numexpr
模块一起用于进一步提升性能。
因此,我们将有两个途径,像这样 -
import numexpr as ne
def numpy_app(df):
a = df.values
N = df.columns.values.astype(int)
return pd.DataFrame((1-(1+a)**-N)/a, columns=df.columns, index=df.index)
def numpy_numexpr_app(df):
a = df.values
N = df.columns.values.astype(int)
return pd.DataFrame(ne.evaluate('(1-(1+a)**-N)/a'), \
columns=df.columns, index=df.index)
上更大的数据集
运行测试 -
In [75]: names = np.random.choice(10000,5000, replace=0)
In [76]: df = pd.DataFrame(np.random.rand(5000,5000), columns=list(names))
# @jezrael's solution using df.apply
In [77]: %timeit df.apply(lambda x: computeAnnuity(x, int(x.name)))
1 loops, best of 3: 3.54 s per loop
In [78]: %timeit numpy_app(df)
1 loops, best of 3: 1.99 s per loop
In [79]: %timeit numpy_numexpr_app(df)
1 loops, best of 3: 393 ms per loop