pandy pythonowe: zastosuj funkcję z argumentami do serii

147

Chcę zastosować funkcję z argumentami do serii w pandach Pythona:

x = my_series.apply(my_function, more_arguments_1)
y = my_series.apply(my_function, more_arguments_2)
...

Dokumentacja opisuje wsparcie dla zastosowania metody, ale nie przyjmuje żadnych argumentów. Czy istnieje inna metoda, która akceptuje argumenty? Albo czy brakuje mi prostego obejścia?

Aktualizacja (październik 2017 r.): Zwróć uwagę, że ponieważ pierwotnie zadano to pytanie, pandy apply()zostały zaktualizowane, aby obsługiwały argumenty pozycyjne i słowa kluczowe, a łącze do dokumentacji powyżej odzwierciedla to teraz i pokazuje, jak uwzględnić każdy typ argumentu.

Abe
źródło
3
Dlaczego po prostu nie użyć functools.partiallub starmap?
Joel Cornett

Odpowiedzi:

170

Nowsze wersje pandy zrobić pozwala przekazać dodatkowe argumenty (patrz nowej dokumentacji ). Więc teraz możesz:

my_series.apply(your_function, args=(2,3,4), extra_kw=1)

Argumenty pozycyjne są dodawane po elemencie serii.


Dla starszej wersji pand:

Dokumentacja jasno to wyjaśnia. Metoda Apply akceptuje funkcję Pythona, która powinna mieć jeden parametr. Jeśli chcesz przekazać więcej parametrów, powinieneś użyć functools.partialsugestii Joela Cornetta w swoim komentarzu.

Przykład:

>>> import functools
>>> import operator
>>> add_3 = functools.partial(operator.add,3)
>>> add_3(2)
5
>>> add_3(7)
10

Możesz również przekazać argumenty słów kluczowych za pomocą partial.

Innym sposobem byłoby utworzenie lambdy:

my_series.apply((lambda x: your_func(a,b,c,d,...,x)))

Ale myślę, że używanie partialjest lepsze.

Bakuriu
źródło
12
W przypadku DataFrame metoda Apply akceptuje argsargument, czyli krotkę zawierającą dodatkowe argumenty pozycyjne lub ** kwds dla nazwanych. Utworzyłem numer, aby mieć to również dla Series.apply () github.com/pydata/pandas/issues/1829
Wouter Overmeire
28
Funkcja została zaimplementowana, będzie w nadchodzącym wydaniu pand
Wes McKinney
4
To dobra odpowiedź, ale pierwsze 2/3 z niej jest teraz naprawdę przestarzałe. IMO, ta odpowiedź mogłaby być ładnie zaktualizowana, będąc po prostu linkiem do nowej dokumentacji oraz krótkim przykładem użycia z argumentami pozycji i / lub słów kluczowych. Tylko FWIW, a nie krytyka oryginalnej odpowiedzi, po prostu skorzystałby na aktualizacji IMO, zwłaszcza że jest to często czytana odpowiedź.
JohnE
@watsonic Dokumentacja została od tego czasu zaktualizowana, a kliknięcie starych łączy prowadzi do aktualnej dokumentacji, która teraz bardzo dobrze odpowiada na to pytanie.
JohnE
Uwaga: Jeśli na przykład przekazujesz pojedynczy argument w postaci łańcucha 'abc', args=('abc')zostanie on oceniony jako trzy argumenty ('a', 'b', 'c'). Aby tego uniknąć, musisz przekazać krotkę zawierającą ciąg, a aby to zrobić, dodaj przecinek na końcu:args=('abc',)
Rocky K
82

Kroki:

  1. Utwórz ramkę danych
  2. Utwórz funkcję
  3. Użyj nazwanych argumentów funkcji w instrukcji Apply.

Przykład

x=pd.DataFrame([1,2,3,4])  

def add(i1, i2):  
    return i1+i2

x.apply(add,i2=9)

Wynikiem tego przykładu jest to, że każda liczba w ramce danych zostanie dodana do liczby 9.

    0
0  10
1  11
2  12
3  13

Wyjaśnienie:

Funkcja „dodaj” ma dwa parametry: i1, i2. Pierwszym parametrem będzie wartość w ramce danych, a drugim to, co przekażemy do funkcji „zastosuj”. W tym przypadku przekazujemy „9” do funkcji stosującej za pomocą argumentu słowa kluczowego „i2”.

Pięść furii
źródło
2
Dokładnie to, czego szukałem. Warto zauważyć, że nie wymaga to tworzenia niestandardowej funkcji tylko do obsługi serii (lub df). Idealny!
Connor
Pozostaje tylko pytanie: jak przekazać argument słowa kluczowego do pierwszego argumentu w add (i1) i wykonać iterację z i2?
Connor
Myślę, że to najlepsza odpowiedź
crypdick
43
Series.apply(func, convert_dtype=True, args=(), **kwds)

args : tuple

x = my_series.apply(my_function, args = (arg1,))
dani_g
źródło
11
Dzięki! Czy możesz wyjaśnić, dlaczego argument args = (arg1,) wymaga przecinka po pierwszym argumencie?
DrMisha
21
@MishaTeplitskiy, potrzebujesz przecinka, aby Python zrozumiał zawartość nawiasów jako krotkę o długości 1.
prooffreader
3
A co z wprowadzeniem argumentów dla func. Więc jeśli chcę złożyć wniosek, w pd.Series.mean(axis=1)jaki sposób mam wpisać axis=1?
Little Bobby Tables
1
Na marginesie, możesz również dodać argument słowa kluczowego bez użycia parametru <args> (np .: x = my_series.apply (my_function, keyword_arg = arg1), gdzie <keyword_arg> jest jednym z parametrów wejściowych mojej_funkcji)
lew
1
ta odpowiedź jest zbyt krótka i niczego nie wyjaśnia
FistOfFury
23

Możesz przekazać dowolną liczbę argumentów do funkcji, która applywywołuje za pośrednictwem nienazwanych argumentów, przekazanych jako krotka do argsparametru lub przez inne argumenty słów kluczowych przechwycone wewnętrznie jako słownik przez kwdsparametr.

Na przykład stwórzmy funkcję, która zwraca True dla wartości od 3 do 6, aw przeciwnym razie False.

s = pd.Series(np.random.randint(0,10, 10))
s

0    5
1    3
2    1
3    1
4    6
5    0
6    3
7    4
8    9
9    6
dtype: int64

s.apply(lambda x: x >= 3 and x <= 6)

0     True
1     True
2    False
3    False
4     True
5    False
6     True
7     True
8    False
9     True
dtype: bool

Ta anonimowa funkcja nie jest zbyt elastyczna. Utwórzmy normalną funkcję z dwoma argumentami do kontrolowania minimalnych i maksymalnych wartości, które chcemy uzyskać w naszej serii.

def between(x, low, high):
    return x >= low and x =< high

Możemy powielić wynik pierwszej funkcji, przekazując nienazwane argumenty do args:

s.apply(between, args=(3,6))

Lub możemy użyć nazwanych argumentów

s.apply(between, low=3, high=6)

Lub nawet połączenie obu

s.apply(between, args=(3,), high=6)
Ted Petrou
źródło