我有一个大型的pandas DataFrame,它的多索引 ['日期',' Int1',' Int2']和单列是浮点数。 目前我正在通过以下方式应用一些规范化:
data.unstack().apply(some_matrix_math, axis=1).stack()
def some_matrix_math(matrix):
#do some matrix math to normalize
return matrix
我正在应用日期'日期' Int1'然后我想把数据框放回到['日期',' Int1',' Int2']。
以上代码可以正常工作,但在大型数据集上却很慢。我想知道是否有更快的方法来做同样的事情?
答案 0 :(得分:0)
我可能有这个错误,但如果我正确理解你想做什么,groupby
可能更适合你想要做的事情。您可以使用data.groupby(level=['Date', 'int1']).apply(some_matrix_math)
这是一个用于演示此数据的示例。此示例将值标准化为具有相同Date
和int1
的行的总和:
In[1]: df = pd.DataFrame(np.arange(4), index=pd.MultiIndex.from_arrays([('a', 'a', 'b', 'b'), (1, 1, 2, 2), (11, 12, 13, 14)], names=['date', 'int1', 'int2']))
In[2]: df
Out[2]:
0
date int1 int2
a 1 11 0
12 1
b 2 13 2
14 3
In[3]: df.groupby(level=['date', 'int1']).apply(lambda x: x/x.sum())
Out[3]:
0
date int1 int2
a 1 11 0.0
12 1.0
b 2 13 0.4
14 0.6
性能方面,对于较小的阵列,groupby
看起来较慢,但对于较大的阵列,您会看到速度增益。
In[69]: df = pd.DataFrame(np.arange(80000), index=pd.MultiIndex.from_arrays([('a', 'b', 'c', 'd')*20000, [1, 2, 3, 4]*20000, np.arange(80000)], names=['date', 'int1', 'int2']))
In[70]: %timeit df.unstack().apply(lambda x: x/x.sum(), axis=1).stack()
83.5 ms ± 8.67 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In[71]: %timeit df.groupby(level=['date', 'int1']).transform(lambda x: x/x.sum())
40.5 ms ± 4.89 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
答案 1 :(得分:0)
在我的函数中,我通过执行以下操作将初始向量转换为ndarray:
def some_matrix_math(matrix):
ndarray = matrix.values
#do some matrix math to normalize
return matrix
然后我使用numpy函数和向量而不是pandas系列,并且运行速度提高了100倍。