2017-07-14 3 views
2

Gegeben ist der folgende Pandas-Datenrahmen mit 60 Elementen.Preisliste von einer längeren Länge auf eine kleinere Länge umrechnen

import pandas as pd 
data = [60,62.75,73.28,75.77,70.28 
    ,67.85,74.58,72.91,68.33,78.59 
    ,75.58,78.93,74.61,85.3,84.63 
    ,84.61,87.76,95.02,98.83,92.44 
    ,84.8,89.51,90.25,93.82,86.64 
    ,77.84,76.06,77.75,72.13,80.2 
    ,79.05,76.11,80.28,76.38,73.3 
    ,72.28,77,69.28,71.31,79.25 
    ,75.11,73.16,78.91,84.78,85.17 
    ,91.53,94.85,87.79,97.92,92.88 
    ,91.92,88.32,81.49,88.67,91.46 
    ,91.71,82.17,93.05,103.98,105] 

data_pd = pd.DataFrame(data, columns=["price"]) 

Gibt es eine Formel dies so neu zu skalieren, so dass für jedes Fenster größer als 20 Elemente aus dem Index 0 indiziert Start i+1, werden die Daten auf 20 Elemente neu skaliert nach unten?

Hier ist eine Schleife, die die Fenster mit den Daten für die Neuskalierung erstellt, ich weiß nur keine Möglichkeit, die Neuskalierung selbst für dieses Problem zu tun. Irgendwelche Vorschläge, wie das gemacht werden könnte?

miniLenght = 20 
rescaledData = [] 
for i in range(len(data_pd)): 
    if(i >= miniLenght): 
     dataForScaling = data_pd[0:i] 
     scaledDataToMinLenght = dataForScaling #do the scaling here so that the length of the rescaled data is always equal to miniLenght 
     rescaledData.append(scaledDataToMinLenght) 

Grundsätzlich nach der Neuskalierung der rescaledData sollte 40-Arrays, die jeweils mit einer Länge von 20 Preisen.

+0

Was machen Sie mit der Neuskalierung? –

+0

Die Frage ist wirklich von einer wissenschaftlichen Arbeit, die ich versuche, das Ergebnis zu reproduzieren, aber ich habe eine harte Zeit, die Re-Skalierung zu tun. [Hier] (http://content.oospress.com/articles/algorithmic-finance/af059#eq3) ist eine Formel, die ich dabei gefunden habe, ich weiß nur nicht, wie sie hier angewendet werden kann. – RaduS

+0

Werfen Sie einen Blick auf [' df.rolling'] (https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.rolling.html). Kann von etwas Nutzen sein. –

Antwort

3

Aus dem Lesen des Papiers sieht es so aus, als ob Sie die Liste auf 20 Indizes zurücksetzen und dann die Daten bei Ihren 20 Indizes interpolieren.

Wir machen die Indizes so wie sie es tun (range(0, len(large), step = len(large)/miniLenght)), dann verwenden Sie numpys interp - es gibt eine Million Möglichkeiten, Daten zu interpolieren. np.interp verwendet eine lineare Interpolation. Wenn Sie zB nach Index 1.5 gefragt haben, erhalten Sie den Mittelwert der Punkte 1 und 2 und so weiter.

So, hier ist eine schnelle Änderung des Codes, es zu tun (nb, könnten wir wahrscheinlich vectorize voll dies mit 'rolling'):

import numpy as np 
miniLenght = 20 
rescaledData = [] 

for i in range(len(data_pd)): 
    if(i >= miniLenght): 
     dataForScaling = data_pd['price'][0:i] 
     #figure out how many 'steps' we have 
     steps = len(dataForScaling) 
     #make indices where the data needs to be sliced to get 20 points 
     indices = np.arange(0,steps, step = steps/miniLenght) 
     #use np.interp at those points, with the original values as given 
     rescaledData.append(np.interp(indices, np.arange(steps), dataForScaling)) 

und der Ausgang ist wie erwartet:

[array([ 60. , 62.75, 73.28, 75.77, 70.28, 67.85, 74.58, 72.91, 
     68.33, 78.59, 75.58, 78.93, 74.61, 85.3 , 84.63, 84.61, 
     87.76, 95.02, 98.83, 92.44]), 
array([ 60. , 63.2765, 73.529 , 74.9465, 69.794 , 69.5325, 
     74.079 , 71.307 , 72.434 , 77.2355, 77.255 , 76.554 , 
     81.024 , 84.8645, 84.616 , 86.9725, 93.568 , 98.2585, 
     93.079 , 85.182 ]),..... 
+0

Vielen Dank @ Jeremycg für die Antwort. Das war es :) Ich werde das Kopfgeld an diese Antwort in 15h vergeben, wenn es mir erlaubt;) – RaduS

+0

Danke! Ich bin froh, dass es funktioniert – jeremycg