我怀疑你在尝试使用 np.vectorize,因为你读到 numpy 的“向量化”是加速 pandas 代码的一种方式。
In [29]: df = pd.DataFrame(np.arange(12).reshape(4,3), columns=['A','B','C'])
In [30]: df
Out[30]:
A B C
0 0 1 2
1 3 4 5
2 6 7 8
3 9 10 11
逐行缓慢的取行均值的方法:
In [31]: df.apply(lambda row: np.mean(row), axis=1)
Out[31]:
0 1.0
1 4.0
2 7.0
3 10.0
dtype: float64
快速的numpy方法:
In [32]: df.to_numpy()
Out[32]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
In [33]: df.to_numpy().mean(axis=1)
Out[33]: array([ 1., 4., 7., 10.])
也就是说,我们得到一个数据帧值的数组,并使用快速编译的方法来计算行均值。
但是要为每一行制作类似于字典的东西:
In [35]: df.apply(lambda row: {str(k):k for k in row}, axis=1)
Out[35]:
0 {'0': 0, '1': 1, '2': 2}
1 {'3': 3, '4': 4, '5': 5}
2 {'6': 6, '7': 7, '8': 8}
3 {'9': 9, '10': 10, '11': 11}
dtype: object
我们必须迭代数组行,就像我们对数据框 apply 所做的那样:
In [36]: [{str(k):k for k in row} for row in df.to_numpy()]
Out[36]:
[{'0': 0, '1': 1, '2': 2},
{'3': 3, '4': 4, '5': 5},
{'6': 6, '7': 7, '8': 8},
{'9': 9, '10': 10, '11': 11}]
数组方法更快:
In [37]: timeit df.apply(lambda row: {str(k):k for k in row}, axis=1)
1.13 ms ± 702 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [38]: timeit [{str(k):k for k in row} for row in df.to_numpy()]
40.8 µs ± 157 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
但是apply 方法返回一个数据帧,而不是一个列表。我怀疑大部分额外的时间都在这一步。
np.vectorize(和np.frompyfunc)也可用于迭代数组,但默认是迭代元素,而不是行或列。一般来说,它们比更显式的迭代要慢(就像我在 [36] 中所做的那样)。
一种从列表中创建数据框的笨方法:
In [53]: %%timeit
...: df1 = pd.DataFrame(['one','two','three','four'],columns=['d'])
...: df1['d'] =[{str(k):k for k in row} for row in df.to_numpy()]
572 µs ± 18.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)