Dlaczego moje pandy nie działają w funkcji "apply" odwołującej się do wielu kolumn? [zamknięte]

zamknięte. to pytanie jest nie powtarzalne lub spowodowane literówkami . Obecnie nie przyjmuje odpowiedzi.

chcesz poprawić to pytanie? Update pytanie więc jest on-topic {[8] } dla Stack Overflow.

Zamknięte 1 rok temu .

Popraw to pytanie

Mam pewne problemy z funkcją Pandy apply, gdy używam wielu kolumn z następującym dataframe

df = DataFrame ({'a' : np.random.randn(6),
                 'b' : ['foo', 'bar'] * 3,
                 'c' : np.random.randn(6)})

I następująca funkcja

def my_test(a, b):
    return a % b

Kiedy spróbuj zastosować tę funkcję za pomocą:

df['Value'] = df.apply(lambda row: my_test(row[a], row[c]), axis=1)

Otrzymuję komunikat o błędzie:

NameError: ("global name 'a' is not defined", u'occurred at index 0')

Nie rozumiem tej wiadomości, zdefiniowałem nazwę poprawnie.

Byłbym bardzo wdzięczny za pomoc w tej sprawie

Update

Dzięki za pomoc. Popełniłem rzeczywiście kilka błędów składniowych w kodzie, indeks należy umieścić". Jednak nadal dostaję ten sam problem, używając bardziej złożonej funkcji, takiej jak:
def my_test(a):
    cum_diff = 0
    for ix in df.index():
        cum_diff = cum_diff + (a - df['a'][ix])
    return cum_diff 
Author: smci, 2013-05-03

6 answers

Wygląda na to, że zapomniałeś o sznurku.

In [43]: df['Value'] = df.apply(lambda row: my_test(row['a'], row['c']), axis=1)

In [44]: df
Out[44]:
                    a    b         c     Value
          0 -1.674308  foo  0.343801  0.044698
          1 -2.163236  bar -2.046438 -0.116798
          2 -0.199115  foo -0.458050 -0.199115
          3  0.918646  bar -0.007185 -0.001006
          4  1.336830  foo  0.534292  0.268245
          5  0.976844  bar -0.773630 -0.570417

BTW, moim zdaniem, sposób postępowania jest bardziej elegancki:

In [53]: def my_test2(row):
....:     return row['a'] % row['c']
....:     

In [54]: df['Value'] = df.apply(my_test2, axis=1)
 387
Author: waitingkuo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-03 08:40:31

Jeśli chcesz obliczyć (kolumna a) % (Kolumna b), nie potrzebujesz apply, po prostu zrób to bezpośrednio:

In [7]: df['a'] % df['c']                                                                                                                                                        
Out[7]: 
0   -1.132022                                                                                                                                                                    
1   -0.939493                                                                                                                                                                    
2    0.201931                                                                                                                                                                    
3    0.511374                                                                                                                                                                    
4   -0.694647                                                                                                                                                                    
5   -0.023486                                                                                                                                                                    
Name: a
 33
Author: herrfz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-03 07:56:43

Powiedzmy, że chcemy zastosować funkcję add5 do kolumn " a " i " b " DataFrame df

def add5(x):
    return x+5

df[['a', 'b']].apply(add5)
 18
Author: Mir_Murtaza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-12 19:18:06

Wszystkie powyższe sugestie działają, ale jeśli chcesz, aby twoje obliczenia były bardziej wydajne, powinieneś skorzystać z operacji wektorowych numpy (jak wskazano tutaj) .

import pandas as pd
import numpy as np


df = pd.DataFrame ({'a' : np.random.randn(6),
             'b' : ['foo', 'bar'] * 3,
             'c' : np.random.randn(6)})

Przykład 1: zapętlenie za pomocą pandas.apply():

%%timeit
def my_test2(row):
    return row['a'] % row['c']

df['Value'] = df.apply(my_test2, axis=1)
Najwolniejszy bieg trwał 7,49 razy dłużej niż najszybszy. To może oznacza, że wynik pośredni jest buforowany. 1000 loops, best of 3: 481 µs na pętlę

Przykład 2: vectorize using pandas.apply():

%%timeit
df['a'] % df['c']
Najwolniejszy bieg trwał 458,85 razy dłużej niż najszybszy. To może oznacza, że wynik pośredni jest buforowany. 10000 pętli, best of 3: 70.9 µs na pętlę

Przykład 3: wektoryzacja przy użyciu tablic numpy:

%%timeit
df['a'].values % df['c'].values
Najwolniejszy bieg trwał 7,98 razy dłużej niż najszybszy. To może oznacza, że wynik pośredni jest buforowany. 100000 pętli, najlepiej z 3: 6.39 µs na pętlę

Więc wektoryzacja przy użyciu tablic numpy poprawiła szybkość o prawie dwa rzędy wielkości.

 11
Author: Blane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-10 01:08:44

Jest to to samo co poprzednie rozwiązanie, ale zdefiniowałem funkcję w df.stosuje się:

df['Value'] = df.apply(lambda row: row['a']%row['c'], axis=1)
 3
Author: shaurya airi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-30 04:47:45

Podałem porównanie wszystkich trzech omówionych powyżej.

Używanie wartości

%timeit df['value'] = df['a'].values % df['c'].values

139 µs ± 1,91 µs na pętlę (średnia ± std. dev. z 7 biegów, po 10000 pętli każdy)

Bez wartości

%timeit df['value'] = df['a']%df['c'] 

216 µs ± 1,86 µs na pętlę (średnia ± std. dev. z 7 biegów, po 1000 pętli każdy)

Apply function

%timeit df['Value'] = df.apply(lambda row: row['a']%row['c'], axis=1)

474 µs ± 5,07 µs na pętlę (średnia ± std. dev. z 7 biegów, po 1000 pętli każdy)

 2
Author: Gursewak Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-17 03:53:41