2012-05-25 4 views
42

sto usando un Pandas DataFrame di fare un test t di riga-saggio come da questo esempio:restituisce Valori multipli panda applicare su un dataframe

import numpy 
import pandas 

df = pandas.DataFrame(numpy.log2(numpy.randn(1000, 4), 
         columns=["a", "b", "c", "d"]) 

df = df.dropna() 

Ora, se io ho "a" e " b "come un gruppo, e" c "e" d "all'altra, sto eseguendo il test t-saggio. Questo è abbastanza banale con i panda, usando apply con axis = 1. Tuttavia, posso restituire un DataFrame della stessa forma se la mia funzione non aggrega o una serie se aggrega.

Normalmente vorrei solo emettere il valore p (quindi, aggregazione) ma vorrei generare un valore aggiuntivo basato su altri calcoli (in altre parole, restituire due valori). Naturalmente posso eseguire due esecuzioni, prima di tutto aggregando i p-value, poi facendo l'altro, ma mi chiedevo se esiste un modo più efficiente per farlo in quanto i dati sono ragionevolmente grandi.

Come esempio del calcolo, una funzione ipotetico sarebbe:

from scipy.stats import ttest_ind 

def t_test_and_mean(series, first, second): 
    first_group = series[first] 
    second_group = series[second] 
    _, pvalue = ttest_ind(first_group, second_group) 

    mean_ratio = second_group.mean()/first_group.mean() 

    return (pvalue, mean_ratio) 

Poi richiamato con

df.apply(t_test_and_mean, first=["a", "b"], second=["c", "d"], axis=1) 

Naturalmente in questo caso restituisce una singola serie con i due tuple come valore .

Invece, ny output previsto sarebbe un DataFrame con due colonne, una per il primo risultato e una per il secondo. È possibile o devo fare due run per i due calcoli, quindi unirli insieme?

+3

Perché stai utilizzando 'apply' in primo luogo? Il tuo risultato è un nuovo 'DataFrame' con una forma diversa dall'input (sia righe che colonne), quindi è un obj completamente nuovo. Potresti semplicemente avere 't_test_and_mean' accettare il tuo dataframe di input (e le colonne da raggruppare per) e restituire un dataframe a 1 riga 2 colonne, senza usare' apply'. – lbolla

+1

@lbolla Bene, alla fine ho finito per farlo nel mio codice. – Einar

risposta

59

Il ritorno di una serie, anziché tupla, dovrebbe produrre un nuovo DataFrame a più colonne. Ad esempio,

return pandas.Series({'pvalue': pvalue, 'mean_ratio': mean_ratio}) 
+0

Riprenderò lunedì, ma se ricordo correttamente tenta di forzare la struttura della colonna originale (terminando così con NA). – Einar

+0

@garrett - Come posso assicurarmi che il risultato restituito da una funzione mantenga il suo ordine "inteso". Il mio caso d'uso è - dopo aver restituito questa serie da una funzione, la sto salvando in un file csv usando df.to_csv. A parte il fatto che naturalmente è stupido e li chiama come A, B, C, D per mantenere il suo ordinamento naturale nel file csv. – ekta

+4

per specificare l'ordine delle colonne, prova a costruire le serie con le liste invece di un dict, ad esempio: 'pandas.Series ([valore_valore, media_ratio], indice = ['valore_valore', 'mean_ratio'])' – Garrett