2017-02-03 3 views
2

Ich habe einen Datenrahmen (ich werde es PeerGroup nennen), die etwa 20 Spalten hat, jede mit einer Reihe von monatlichen Renditen für 20 verschiedene Fonds, aus einem Jahrzehnt zurück. Ich versuche herauszufinden, ob sich die durchschnittliche Rendite in den letzten drei Jahren statistisch von der Durchschnittsleistung für den gesamten Track Record unterscheidet.Anwenden von T-Test auf jede Spalte in Dataframe

Derzeit mit Pandas, kann ich die Spalten einer nach dem anderen testen, wie so:

import pandas as pd 
import statsmodels as st 
PeerGroup = pd.read_excel['File\Path.xlsx'] 
df['Fund1'] = st.ttest_ind(PeerGroup['Column1'], PeerGroup['Column1'].tail(36), equal_var='False') 

jedoch, wenn überhaupt möglich, ich möchte den Test auf jeder Spalte in der Datenrahmen laufen in ein Schuss. Mein bester Gedanke war, so etwas zu machen, aber es wird zu einem IndexError. Irgendwelche Gedanken?

df['All_Funds'] = PeerGroup[PeerGroup.columns[1:]].apply(lambda x: st.ttest_ind(PeerGroup[x], PeerGroup[x].tail(36), equal_var='False')) 

Antwort

1

Die pandas.DataFrame.apply Methode, die Sie hier verwenden ist jede der Spalten Ihres Datensatzes in Ihrer lambda Funktion als individuelle Series Fütterung, aber Ihre lambda geschrieben wird, als wenn Sie stattdessen einen Spaltennamen bekommen.

Um, hier ist ein triviales Beispiel zu illustrieren:

>>> df = pd.DataFrame({'a': [1,2,3], 'b': [4,5,6]}) 

Wenn wir die Methode Körper mit einem print ersetzen, zu sehen, was an die Funktion übergeben wird:

>>> df.apply(lambda x: print(x)) 
<<< 0 1 
    1 2 
    2 3 
    Name: a, dtype: int64 
    0 4 
    1 5 
    2 6 
    Name: b, dtype: int64 

Ihr Methodenaufruf isn‘ t funktioniert, weil Sie Ihre DataFrame mit einer Reihe von Series Objekte indizieren, von denen jede eine Spalte Ihres Datasets ist, die pandas nicht weiß, was zu tun ist mit:

>>> df.apply(lambda x: df[x]) 
<<< [...] 
<<< IndexError 

(als kleines beiseite, Sie kann Index ein DataFrame mit einem Series der richtige "Form"; In diesem Spielzeugbeispiel versuchen Sie z.B. df[pd.Series(['a'])])

Da Sie bereits Ihre Spalte von Interesse haben, ist die Lösung zu vereinfachen. Dies sollte funktionieren:

df['All_Funds'] = PeerGroup[PeerGroup.columns[1:]].apply(lambda x: st.ttest_ind(x, x.tail(36), equal_var='False')) 
+0

auch zur besseren Lesbarkeit, könnte ich 'X' für 'fund' als Variable der Wahl empfehlen, tauschen? –

0

Statsmodels ttest_ind wird die Berechnung der t-Test in einem vektorisierten Weise.

Zum Beispiel

>>> np.random.seed(123987) 
>>> x = np.random.randn(50,5) 
>>> import statsmodels.api as sm 
>>> sm.stats.ttest_ind(x[:30], x[30:]) 
    (array([-0.95151202, 0.34686484, -1.85364701, -0.46793673, 0.06192139]), 
    array([ 0.34611141, 0.73020901, 0.06994078, 0.64194762, 0.95088256]), 48.0) 

und mit expliziter Schleife überprüfen

>>> np.array([sm.stats.ttest_ind(xi[:30], xi[30:])[:2] for xi in x.T]).T 
array([[-0.95151202, 0.34686484, -1.85364701, -0.46793673, 0.06192139], 
     [ 0.34611141, 0.73020901, 0.06994078, 0.64194762, 0.95088256]]) 

Das gleiche sollte mit einem Pandas Datenrahmen arbeiten.

Hinweis, wenn die zwei Reihen, die im t-Test verglichen werden, überlappen, dann sind die zwei Proben nicht unabhängig. Es ist besser zu prüfen, ob der Mittelwert des ersten Teils der Serie der Mittelwert des zweiten Teils der Serie ist.
Dies setzt immer noch voraus, dass die Beobachtungen in etwa seriell unkorreliert sind.

bearbeiten
Es sieht aus wie die importierte Funktion SciPy bezieht.Statistiken und keine Statistikmodelle, die ein anderes Schlüsselwort für die Varianzannahme verwenden. Beide arbeiten in ähnlicher Weise (Ausgabe umformatiert Zahlen auszurichten)

>>> sm.stats.ttest_ind(x[:30], x[30:], usevar='unequal') 
    (array([-0.91734136, 0.36226976, -1.91402235, -0.45593946, 0.06075814]), 
    array([ 0.36512018, 0.71880355, 0.06199039, 0.6510849 , 0.95186872]), 
    array([ 35.6978717 , 46.16729003, 44.9965459 , 37.18892135, 38.18591126])) 

>>> from scipy import stats 
>>> stats.ttest_ind(x[:30], x[30:], equal_var=False) 
Ttest_indResult(
statistic=array([-0.91734136, 0.36226976, -1.91402235, -0.45593946, 0.06075814]), 
    pvalue=array([ 0.36512018, 0.71880355, 0.06199039, 0.6510849 , 0.95186872])) 
Verwandte Themen