2014-10-17 23 views
5

Podczas korzystania z metody df.mean() otrzymuję wynik, w którym podana jest średnia dla każdej kolumny. Teraz powiedzmy, że chcę średnią pierwszej kolumny i sumę drugiej. Czy jest jakiś sposób na zrobienie tego? Nie chcę demontować i ponownie składać ramek danych.Pandy: zastosowanie różnych funkcji do różnych kolumn

Mój początkowy pomysł był zrobić coś na wzór pandas.groupby.agg() tak:

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') 

Ale oczywiście to nie działa. Wydaje się, że przekazanie dyktatury byłoby intuicyjnym sposobem na zrobienie tego, ale czy istnieje inny sposób (ponownie bez demontowania i ponownego tworzenia DataFrame)?

Odpowiedz

1

myślę, że można użyć metody agg ze słownikiem jako argumentu . Na przykład:

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

Można spróbować Zamknięcie:

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

To właściwie całkiem niezłe. Moje obejście polegało na wstawieniu kolumny do ramki danych, wykonaniu grupy w tej kolumnie, a następnie przekazaniu dyktatu do metody zbiorczej. – pbreach

+0

Dziękujemy! Zauważam, że to się nie powiedzie, jeśli w ramce DataFrame jest więcej kolumn niż w funkcji dyktafon. @ Bill-Leton też to widziałeś? –

+0

Pełna implementacja powinna zawierać klauzulę tryout KeyError, która zwraca funkcję tożsamości: lambda x: x –

1

Wystarczy sobie w obliczu tej sytuacji i wpadł na następujący:

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 
Powiązane problemy