por que os pandas rolantes usam o ndarray de dimensão única

Eu estava motivado para usar pandasrolling para executar uma regressão multifatorial contínua (esta pergunta éNÃO sobre rolagem de regressão multifatorial). Eu esperava que eu fosse capaz de usarapply após umdf.rolling(2) e pegue a resultantepd.DataFrame extrair o ndarray com.values e execute a multiplicação de matrizes necessária. Não funcionou dessa maneira.

Aqui está o que eu encontrei:

import pandas as pd
import numpy as np

np.random.seed([3,1415])
df = pd.DataFrame(np.random.rand(5, 2).round(2), columns=['A', 'B'])
X = np.random.rand(2, 1).round(2)

Como são os objetos:

print "\ndf = \n", df
print "\nX = \n", X
print "\ndf.shape =", df.shape, ", X.shape =", X.shape

df = 
      A     B
0  0.44  0.41
1  0.46  0.47
2  0.46  0.02
3  0.85  0.82
4  0.78  0.76

X = 
[[ 0.93]
 [ 0.83]]

df.shape = (5, 2) , X.shape = (2L, 1L)

A multiplicação de matrizes se comporta normalmente:

df.values.dot(X)

array([[ 0.7495],
       [ 0.8179],
       [ 0.4444],
       [ 1.4711],
       [ 1.3562]])

O uso de apply para executar o produto de linha a linha se comporta conforme o esperado:

df.apply(lambda x: x.values.dot(X)[0], axis=1)

0    0.7495
1    0.8179
2    0.4444
3    1.4711
4    1.3562
dtype: float64

Groupby -> Apply se comporta como eu esperava:

df.groupby(level=0).apply(lambda x: x.values.dot(X)[0, 0])

0    0.7495
1    0.8179
2    0.4444
3    1.4711
4    1.3562
dtype: float64

Mas quando eu corro:

df.rolling(1).apply(lambda x: x.values.dot(X))

Eu recebo:

AttributeError: o objeto 'numpy.ndarray' não possui atributos 'valores'

Ok, então os pandas estão usandondarray dentro do seurolling implementação. Eu posso cuidar disso. Ao invés de usar.values para obter ondarray, vamos tentar:

df.rolling(1).apply(lambda x: x.dot(X))

formas (1,) e (2,1) não alinhadas: 1 (dim 0)! = 2 (dim 0)

Esperar! O que?!

Então, criei uma função personalizada para analisar o que está rolando.

def print_type_sum(x):
    print type(x), x.shape
    return x.sum()

Então correu:

print df.rolling(1).apply(print_type_sum)

<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
      A     B
0  0.44  0.41
1  0.46  0.47
2  0.46  0.02
3  0.85  0.82
4  0.78  0.76

Meu resultantepd.DataFrame é o mesmo, isso é bom. Mas imprimiu 10 dimensões unidimensionaisndarray objetos. Sobrerolling(2)

print df.rolling(2).apply(print_type_sum)

<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
      A     B
0   NaN   NaN
1  0.90  0.88
2  0.92  0.49
3  1.31  0.84
4  1.63  1.58

A mesma coisa, espera saída, mas imprimiu 8ndarray objetos.rolling está produzindo uma única dimensãondarray de comprimentowindow para cada coluna, em oposição ao que eu esperava, que era umndarray de forma(window, len(df.columns)).

A pergunta é por que?

Agora não tenho como executar facilmente uma regressão multifatorial contínua.

questionAnswers(4)

yourAnswerToTheQuestion