Wie pandas Rollen-Objekte arbeiten?

Edit: ich kondensierten dieser Frage gegeben, dass es wohl zu sehr involviert, um mit zu beginnen. Das Fleisch der Frage in Fett unten.

Ich würde gerne wissen, mehr über das Objekt, das tatsächlich erstellt, wenn Sie DataFrame.rolling oder Series.rolling:

print(type(df.rolling))
<class 'pandas.core.window.Rolling'>

Etwas hintergrund: betrachten Sie die oft verwendete alternative mit np.as_strided. Dieses code-snippet selbst ist nicht wichtig, aber Ihr Ergebnis ist mein Bezugspunkt, diese Frage zu stellen.

def rwindows(a, window):
    if a.ndim == 1:
        a = a.reshape(-1, 1)
    shape = a.shape[0] - window + 1, window, a.shape[-1]
    strides = (a.strides[0],) + a.strides
    windows = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
    return np.squeeze(windows)

Hier rwindows wird eine 1d-oder 2d - ndarray - und build-rolling "Blöcke" gleich der angegebenen Größe der Fenster (wie unten). Wie funktioniert ein .rolling Objekt zu vergleichen, um die ndarray Ausgabe unten? Ist es ein iterator, mit bestimmten gespeicherten Attribute für jeden block? Oder etwas ganz anderes? Ich habe versucht, das Spiel mit der tab-Taste auf das Objekt mit Attributen/Methoden wie __dict__ und _get_index() und Sie ' re nicht zu sagen mir viel. Ich habe auch gesehen, ein _create_blocks Methode in der pandas-ist es überhaupt ähneln die strided Methode?

# as_strided version

a = np.arange(5)
print(rwindows(a, 3))           # 1d input
[[0 1 2]
 [1 2 3]
 [2 3 4]]

b = np.arange(10).reshape(5,2)
print(rwindows(b, 4))           # 2d input
[[[0 1]
  [2 3]
  [4 5]
  [6 7]]

 [[2 3]
  [4 5]
  [6 7]
  [8 9]]]

Teil 2, extra credit

Mit Hilfe der NumPy-Ansatz oben (OLS Umsetzung hier) ist notwendig durch die Tatsache, dass func innerhalb pandas.core.Fenster.Ins Rollen.bewerben muss

produzieren einem einzigen Wert aus einer ndarray-Eingang *args und **kwargs sind
an die Funktion übergeben

Also das argument kann nicht sein, ein anderes Rollen-Objekt. I. e.

def prod(a, b):
    return a * b
df.rolling(3).apply(prod, args=((df + 2).rolling(3),))
-----------------------------------------------------------------------
...
TypeError: unsupported operand type(s) for *: 'float' and 'Rolling'

Also das ist wirklich, wo meine Frage oben stammt. Warum ist es, dass die übergebene Funktion muss ein NumPy-array und erzeugen einen einzelnen skalaren Wert, und was hat das zu tun mit der Gestaltung einer .rolling Objekt?

  • Ich denke, diese Frage ist zu weit gefasst und sollte genauer sein, ohne die Verzweigung in mehrere Fragen
InformationsquelleAutor Brad Solomon | 2017-07-22
Schreibe einen Kommentar