python panda: menerapkan fungsi dengan argumen ke seri

147

Saya ingin menerapkan fungsi dengan argumen ke seri di python panda:

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

The dokumentasi menggambarkan dukungan untuk menerapkan metode, tetapi tidak menerima argumen. Apakah ada metode berbeda yang menerima argumen? Atau, apakah saya melewatkan solusi sederhana?

Pembaruan (Oktober 2017): Perhatikan bahwa sejak pertanyaan ini awalnya ditanyakan bahwa panda apply()telah diperbarui untuk menangani argumen posisi dan kata kunci dan tautan dokumentasi di atas sekarang mencerminkan hal itu dan menunjukkan bagaimana cara memasukkan kedua jenis argumen.

Abe
sumber
3
Kenapa tidak pakai saja functools.partial, atau starmap?
Joel Cornett
1
Lihat DataFrame.applydokumen dan Series.applydokumen
Martin Thoma

Jawaban:

170

Versi panda yang lebih baru memungkinkan Anda memberikan argumen tambahan (lihat dokumentasi baru ). Jadi sekarang Anda bisa melakukannya:

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

Argumen posisional ditambahkan setelah elemen seri.


Untuk versi panda yang lebih lama:

Dokumentasi menjelaskan hal ini dengan jelas. Metode yang berlaku menerima fungsi python yang seharusnya memiliki parameter tunggal. Jika Anda ingin memberikan lebih banyak parameter, Anda harus menggunakan functools.partialseperti yang disarankan oleh Joel Cornett dalam komentarnya.

Sebuah contoh:

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

Anda juga dapat menggunakan argumen kata kunci menggunakan partial.

Cara lain adalah dengan membuat lambda:

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

Tapi saya pikir menggunakan partiallebih baik.

Bakuriu
sumber
12
Untuk DataFrame berlaku metode menerima argsargumen, yang merupakan tuple memegang argumen posisi tambahan atau ** kwds untuk yang bernama. Saya membuat masalah untuk memiliki ini juga untuk Series.apply () github.com/pydata/pandas/issues/1829
Wouter Overmeire
28
Fitur telah diterapkan, akan ada dalam rilis panda mendatang
Wes McKinney
4
Ini adalah jawaban yang bagus tetapi 2/3 pertama benar-benar usang sekarang. IMO, jawaban ini dapat diperbarui dengan baik dengan hanya menjadi tautan ke dokumentasi baru ditambah contoh singkat tentang cara menggunakan dengan posisi dan / atau argumen kata kunci. Hanya FWIW dan bukan kritik terhadap jawaban asli, hanya akan mendapat manfaat dari pembaruan IMO, terutama karena itu adalah jawaban yang sering dibaca.
JohnE
@watsonic Dokumentasi telah diperbarui dan mengklik tautan lama mengarah ke dokumentasi saat ini yang sekarang menjawab pertanyaan dengan sangat baik.
JohnE
Catatan: Jika Anda memberikan argumen string tunggal, misalnya 'abc', maka args=('abc')akan dievaluasi sebagai tiga argumen ('a', 'b', 'c'). Untuk menghindari hal ini, Anda harus memberikan tuple yang berisi string, dan untuk itu, sertakan tanda koma:args=('abc',)
Rocky K
82

Langkah:

  1. Buat bingkai data
  2. Buat fungsi
  3. Gunakan argumen fungsi yang disebutkan dalam pernyataan yang berlaku.

Contoh

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

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

x.apply(add,i2=9)

Hasil dari contoh ini adalah bahwa setiap angka dalam kerangka data akan ditambahkan ke angka 9.

    0
0  10
1  11
2  12
3  13

Penjelasan:

Fungsi "add" memiliki dua parameter: i1, i2. Parameter pertama akan menjadi nilai dalam bingkai data dan yang kedua adalah apa pun yang kita berikan ke fungsi "apply". Dalam hal ini, kami meneruskan "9" ke fungsi terapkan menggunakan argumen kata kunci "i2".

Tinjuan kemarahan
sumber
2
Persis apa yang saya cari. Khususnya, ini tidak perlu membuat fungsi kustom hanya untuk menangani Seri (atau df). Sempurna!
Connor
Satu-satunya pertanyaan yang tersisa adalah: Bagaimana cara mengirimkan argumen kata kunci ke argumen pertama di add (i1) dan beralih dengan i2?
Connor
Saya pikir ini adalah jawaban terbaik
crypdick
43
Series.apply(func, convert_dtype=True, args=(), **kwds)

args : tuple

x = my_series.apply(my_function, args = (arg1,))
dani_g
sumber
11
Terima kasih! Bisakah Anda menjelaskan mengapa args = (arg1,) membutuhkan koma setelah argumen pertama?
DrMisha
21
@MishaTeplitskiy, Anda memerlukan koma agar Python memahami konten tanda kurung menjadi tupel panjang 1.
prooffreader
3
Bagaimana dengan memasukkan args untuk func. Jadi, jika saya ingin menerapkan pd.Series.mean(axis=1)bagaimana cara memasukkan axis=1?
Little Bobby Tables
1
Sebagai catatan tambahan, Anda juga dapat menambahkan argumen kata kunci tanpa menggunakan parameter <args> (mis: x = my_series.apply (my_function, keyword_arg = arg1), di mana <keyword_arg> adalah salah satu parameter input dari my_function)
lev
1
tanggapan ini terlalu singkat dan tidak menjelaskan apa pun
FistOfFury
23

Anda dapat meneruskan sejumlah argumen ke fungsi yang applymemanggil argumen yang tidak disebutkan namanya, dilewatkan sebagai tuple ke argsparameter, atau melalui argumen kata kunci lain yang ditangkap secara internal sebagai kamus berdasarkan kwdsparameter.

Misalnya, mari kita membangun fungsi yang mengembalikan True untuk nilai antara 3 dan 6, dan False sebaliknya.

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

Fungsi anonim ini tidak terlalu fleksibel. Mari kita buat fungsi normal dengan dua argumen untuk mengontrol nilai min dan maks yang kita inginkan di Seri kita.

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

Kami dapat mereplikasi output dari fungsi pertama dengan memberikan argumen tanpa nama ke args:

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

Atau kita bisa menggunakan argumen yang disebutkan

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

Atau bahkan kombinasi keduanya

s.apply(between, args=(3,), high=6)
Ted Petrou
sumber