2014-10-17 14 views
5

Quando si utilizza df.mean() viene visualizzato un risultato in cui viene fornita la media per ogni colonna. Ora diciamo che voglio la media della prima colonna e la somma del secondo. C'è un modo per fare questo? Non voglio dover smontare e rimontare il dataframe.Panda: applica diverse funzioni a diverse colonne

La mia idea iniziale era di fare qualcosa sulla falsariga di pandas.groupby.agg() in questo modo:

df = pd.DataFrame(np.random.random((10,2)), columns=['A','B']) 
df.apply({'A':np.mean, 'B':np.sum}, axis=0) 

Traceback (most recent call last): 

    File "<ipython-input-81-265d3e797682>", line 1, in <module> 
    df.apply({'A':np.mean, 'B':np.sum}, axis=0) 

    File "C:\Users\Patrick\Anaconda\lib\site-packages\pandas\core\frame.py", line 3471, in apply 
    return self._apply_standard(f, axis, reduce=reduce) 

    File "C:\Users\Patrick\Anaconda\lib\site-packages\pandas\core\frame.py", line 3560, in _apply_standard 
    results[i] = func(v) 

TypeError: ("'dict' object is not callable", u'occurred at index A') 

Ma è chiaro che questo non funziona. Sembra che passare un dict sarebbe un modo intuitivo per farlo, ma c'è un altro modo (ancora senza smontare e rimontare il DataFrame)?

risposta

1

Penso che si può utilizzare il metodo agg con un dizionario come argomento . Ad esempio:

df = pd.DataFrame({'A': [0, 1, 2], 'B': [3, 4, 5]}) 

df = 
A B 
0 0 3 
1 1 4 
2 2 5 

df.agg({'A': 'mean', 'B': sum}) 

A  1.0 
B 12.0 
dtype: float64 
11

Si può provare una chiusura:

def multi_func(functions): 
    def f(col): 
     return functions[col.name](col) 
    return f 

df = pd.DataFrame(np.random.random((10, 2)), columns=['A', 'B']) 
result = df.apply(multi_func({'A': np.mean, 'B': np.sum})) 
+0

Questo è davvero carino. La mia soluzione era inserire una colonna di quelli nel dataframe, facendo groupby su quella colonna e poi passando un dict al metodo di aggregazione. – pbreach

+0

Grazie! Ho notato che questo fallisce se ci sono più colonne nel DataFrame di chiavi nella funzione dict. @ bill-lascia che hai visto anche tu? –

+0

Un'implementazione completa dovrebbe includere una clausola KeyError di prova che restituisce una funzione di identità: lambda x: x –

1

Proprio di fronte a questa situazione me stesso e si avvicinò con la seguente:

In [1]: import pandas as pd 

In [2]: df = pd.DataFrame([['one', 'two'], ['three', 'four'], ['five', 'six']], 
    ...:     columns=['A', 'B']) 

In [3]: df 
Out[3]: 
     A  B 
0 one two 
1 three four 
2 five six 

In [4]: converters = {'A': lambda x: x[:1], 'B': lambda x: x.replace('o', '')} 

In [5]: new = pd.DataFrame.from_dict({col: series.apply(converters[col]) 
    ...:        if col in converters else series 
    ...:        for col, series in df.iteritems()}) 

In [6]: new 
Out[6]: 
    A B 
0 o tw 
1 t fur 
2 f six 
Problemi correlati