优化pandas unstack()。apply()。stack()

时间:2017-09-29 20:17:01

标签: python pandas optimization

我有一个大型的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']。

以上代码可以正常工作,但在大型数据集上却很慢。我想知道是否有更快的方法来做同样的事情?

2 个答案:

答案 0 :(得分:0)

我可能有这个错误,但如果我正确理解你想做什么,groupby可能更适合你想要做的事情。您可以使用data.groupby(level=['Date', 'int1']).apply(some_matrix_math)

的内容

这是一个用于演示此数据的示例。此示例将值标准化为具有相同Dateint1的行的总和:

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倍。