2017-05-23 3 views
2

Lets sagen, dass ich eine pandas.Dataframe haben, die wie folgt aussieht:Use Map-Funktion mit Teilmengen eines Pandas Serie oder Datenrahmen

c1 | c2 
------- 
1 | 5 
2 | 6 
3 | 7 
4 | 8 
..... 
1 | 7 

und ich bin auf der Suche zur Karte eine Funktion (DataFrame.corr), aber ich möchte Es dauert n Reihen auf einmal. Das Ergebnis sollte eine Reihe mit den Korrelationswerten sein, die kürzer als der ursprüngliche DataFrame sein würden, oder mit einigen Werten, die keine vollständigen n Datenzeilen erhalten haben.

Gibt es eine Möglichkeit, dies zu tun und wie? Ich habe die DataFrame- und Map-, Apply-, Filter-Dokumentation durchgesehen, aber es scheint keine offensichtliche oder saubere Lösung zu geben.

Antwort

3

Mit Pandas 0,20 wird mit rolling mit corr ein mehrfach indizierter Datenrahmen erstellt. Sie können danach in Scheiben schneiden, um zu bekommen, wonach Sie suchen.

Betrachten Sie die Datenrahmen df

np.random.seed([3,1415]) 
df = pd.DataFrame(np.random.randint(10, size=(10, 2)), columns=['c1', 'c2']) 

    c1 c2 
0 0 2 
1 7 3 
2 8 7 
3 0 6 
4 8 6 
5 0 2 
6 0 4 
7 9 7 
8 3 2 
9 4 3 

rolling + corr ... pandas 0.20.x

df.rolling(5).corr().dropna().c1.xs('c2', level=1) 
# Or equivalently 
# df.rolling(5).corr().stack().xs(['c1', 'c2'], level=[1, 2]) 

4 0.399056 
5 0.399056 
6 0.684653 
7 0.696074 
8 0.841136 
9 0.762187 
Name: c1, dtype: float64 

rolling + corr ... pandas 0.19.x oder vor
Vor 0,20, rolling + corr produzierte eine pd.Panel

df.rolling(5).corr().loc[:, 'c1', 'c2'].dropna() 

4 0.399056 
5 0.399056 
6 0.684653 
7 0.696074 
8 0.841136 
9 0.762187 
Name: c2, dtype: float64 

numpy + as_strided
Allerdings habe ich mit den oben genannten Antworten nicht zufrieden war. Unten ist eine spezialisierte Funktion, die einen nx2 Datenrahmen nimmt und eine Reihe der rollenden Korrelationen zurückgibt. DISCLAIMER Dies verwendet einige fortgeschrittene Techniken und sollte wirklich nur verwendet werden, wenn Sie wissen, was das tut. Das heißt, wenn Sie eine detaillierte Aufschlüsselung der Funktionsweise benötigen ... dann ist es wahrscheinlich nicht für Sie.

from numpy.lib.stride_tricks import as_strided as strided 

def rolling_correlation(a, w): 
    n, m = a.shape[0], 2 
    s1, s2 = a.strides 
    b = strided(a, (m, w, n - w + 1), (s2, s1, s1)) 
    b_mb = b - b.mean(1, keepdims=True) 
    b_ss = (b_mb ** 2).sum(1) ** .5 
    return (b_mb[0] * b_mb[1]).sum(0)/(b_ss[0] * b_ss[1]) 

def rolling_correlation_df(df, w): 
    a = df.values 
    return pd.Series(rolling_correlation(a, w), df.index[w-1:]) 

rolling_correlation_df(df, 5) 

4 0.399056 
5 0.399056 
6 0.684653 
7 0.696074 
8 0.841136 
9 0.762187 
dtype: float64 

Zeit
kleine Daten

%timeit rolling_correlation_df(df, 5) 
10000 loops, best of 3: 79.9 µs per loop 

%timeit df.rolling(5).corr().stack().xs(['c1', 'c2'], level=[1, 2]) 
100 loops, best of 3: 14.6 ms per loop 

große Daten

np.random.seed([3,1415]) 
df = pd.DataFrame(np.random.randint(10, size=(10000, 2)), columns=['c1', 'c2']) 

%timeit rolling_correlation_df(df, 5) 
1000 loops, best of 3: 615 µs per loop 

%timeit df.rolling(5).corr().stack().xs(['c1', 'c2'], level=[1, 2]) 
1 loop, best of 3: 1.98 s per loop 
+0

Das ist genau das, was ich war lo ok für !! Vielen Dank – Adam

Verwandte Themen