Byłem zmotywowany do korzystania z funkcji pandy rolling
do wykonywania toczącej się wieloczynnikowej regresji (to pytanie jest NOT o toczącej się regresji wieloczynnikowej). Spodziewałem się, że będę mógł użyć apply
po df.rolling(2)
i pobrać wynikowy pd.DataFrame
wyodrębnić ndarray z .values
i wykonać wymagane mnożenie macierzy. To nie działało w ten sposób.Dlaczego pandy toczące się używają pojedynczego wymiaru ndarray
Oto co znalazłem:
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)
Co zrobić obiekty wyglądać następująco:
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)
Mnożenie macierzy zachowuje się normalnie:
df.values.dot(X)
array([[ 0.7495],
[ 0.8179],
[ 0.4444],
[ 1.4711],
[ 1.3562]])
Korzystanie zastosować, aby wykonać kolejny wiersz kropki produkt zachowuje się zgodnie z oczekiwaniami:
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 -> Zastosuj zachowuje się jak bym się spodziewać:
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
Ale kiedy biegnę:
df.rolling(1).apply(lambda x: x.values.dot(X))
uzyskać:
AttributeError: 'numpy.ndarray' object has no attribute 'values'
Ok, więc jest pand za pomocą prostej ndarray
w ramach implementacji rolling
. Mogę sobie z tym poradzić. Zamiast używać .values
uzyskać ndarray
, spróbujmy:
df.rolling(1).apply(lambda x: x.dot(X))
shapes (1,) and (2,1) not aligned: 1 (dim 0) != 2 (dim 0)
Czekaj! Co?!
Stworzyłem więc niestandardową funkcję, aby sprawdzić, co się dzieje.
def print_type_sum(x):
print type(x), x.shape
return x.sum()
Potem pobiegł:
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
My wynikające pd.DataFrame
jest taka sama, to jest dobre. Ale wydrukowano 10 pojedynczych wymiarów obiektów ndarray
. Co o rolling(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
samo, ale oczekiwać wyjście drukowane 8 ndarray
obiektów. rolling
produkuje jednowymiarowy ndarray
o długości window
dla każdej kolumny, w przeciwieństwie do tego, co oczekiwałem, który był ndarray
o kształcie (window, len(df.columns))
.
Pytanie brzmi, dlaczego?
Nie mam teraz sposobu na łatwe uruchomienie toczącej się regresji wieloczynnikowej.
Jest to [znany problem] (http: // stackoverflow.com/a/21026837/5276797). Niedawno zapytałam o to Jeffa, możesz przeczytać jego odpowiedź w komentarzach! – IanS
Co to jest najnowocześniejsze rozwiązanie od Pandy 0.20? Wygląda na to, że wprowadzono wiele ulepszeń. Czy cel w OP możliwy do osiągnięcia za pomocą rolling(). Apply() bezpośrednio? – Zhang18