Saya ingin menerapkan fungsi kustom saya (itu menggunakan tangga jika-lain) sampai enam kolom ini ( ERI_Hispanic
, ERI_AmerInd_AKNatv
, ERI_Asian
, ERI_Black_Afr.Amer
, ERI_HI_PacIsl
, ERI_White
) di setiap baris dataframe saya.
Saya sudah mencoba berbagai metode dari pertanyaan lain tetapi sepertinya masih belum menemukan jawaban yang tepat untuk masalah saya. Bagian penting dari ini adalah bahwa jika orang tersebut dianggap sebagai Hispanik mereka tidak dapat dihitung sebagai hal lain. Bahkan jika mereka memiliki "1" di kolom etnis lain mereka masih dianggap sebagai Hispanik bukan dua atau lebih ras. Demikian pula, jika jumlah semua kolom ERI lebih besar dari 1 mereka dihitung sebagai dua atau lebih ras dan tidak dapat dihitung sebagai etnis yang unik (kecuali untuk Hispanik). Semoga ini masuk akal. Bantuan apa pun akan sangat dihargai.
Hampir seperti melakukan for for melalui setiap baris dan jika setiap catatan memenuhi kriteria mereka ditambahkan ke satu daftar dan dihilangkan dari aslinya.
Dari kerangka data di bawah ini saya perlu menghitung kolom baru berdasarkan spesifikasi berikut dalam SQL:
========================= KRITERIA ======================== =======
IF [ERI_Hispanic] = 1 THEN RETURN “Hispanic”
ELSE IF SUM([ERI_AmerInd_AKNatv] + [ERI_Asian] + [ERI_Black_Afr.Amer] + [ERI_HI_PacIsl] + [ERI_White]) > 1 THEN RETURN “Two or More”
ELSE IF [ERI_AmerInd_AKNatv] = 1 THEN RETURN “A/I AK Native”
ELSE IF [ERI_Asian] = 1 THEN RETURN “Asian”
ELSE IF [ERI_Black_Afr.Amer] = 1 THEN RETURN “Black/AA”
ELSE IF [ERI_HI_PacIsl] = 1 THEN RETURN “Haw/Pac Isl.”
ELSE IF [ERI_White] = 1 THEN RETURN “White”
Komentar: Jika Bendera ERI untuk Hispanik benar (1), karyawan tersebut diklasifikasikan sebagai "Hispanik"
Komentar: Jika lebih dari 1 Bendera ERI non-Hispanik benar, kembalikan "Dua atau Lebih"
====================== DATAFRAME =============================
lname fname rno_cd eri_afr_amer eri_asian eri_hawaiian eri_hispanic eri_nat_amer eri_white rno_defined
0 MOST JEFF E 0 0 0 0 0 1 White
1 CRUISE TOM E 0 0 0 1 0 0 White
2 DEPP JOHNNY 0 0 0 0 0 1 Unknown
3 DICAP LEO 0 0 0 0 0 1 Unknown
4 BRANDO MARLON E 0 0 0 0 0 0 White
5 HANKS TOM 0 0 0 0 0 1 Unknown
6 DENIRO ROBERT E 0 1 0 0 0 1 White
7 PACINO AL E 0 0 0 0 0 1 White
8 WILLIAMS ROBIN E 0 0 1 0 0 0 White
9 EASTWOOD CLINT E 0 0 0 0 0 1 White
Jawaban:
OK, dua langkah untuk ini - pertama adalah menulis fungsi yang melakukan terjemahan yang Anda inginkan - Saya telah memberikan contoh berdasarkan pseudo-code Anda:
Anda mungkin ingin membahas ini, tetapi tampaknya melakukan trik - perhatikan bahwa parameter yang masuk ke fungsi dianggap sebagai objek Seri berlabel "baris".
Selanjutnya, gunakan fungsi terapkan dalam panda untuk menerapkan fungsi - misalnya
Perhatikan sumbu = 1 specifier, itu berarti bahwa aplikasi dilakukan pada satu baris, bukan pada level kolom. Hasilnya di sini:
Jika Anda puas dengan hasil itu, jalankan lagi, simpan hasilnya ke kolom baru di kerangka data asli Anda.
Kerangka data yang dihasilkan terlihat seperti ini (gulir ke kanan untuk melihat kolom baru):
sumber
df.apply(label_race, axis=1)
return 'Other'
baris terakhirreturn row['rno_defined']
yang seharusnya ganti nilai dari kolom itu dalam kasus-kasus di mana set pernyataan if / then tidak menemukan kecocokan (yaitu di mana saat ini, Anda melihat 'Lainnya').df.apply(lambda row: label_race (row),axis=1)
kedf.apply(label_race, axis=1)
Karena ini adalah hasil Google pertama untuk 'kolom baru dari orang lain', berikut adalah contoh sederhana:
Jika Anda mendapatkan,
SettingWithCopyWarning
Anda dapat melakukannya dengan cara ini juga:Sumber: https://stackoverflow.com/a/12555510/243392
Dan jika nama kolom Anda termasuk spasi Anda dapat menggunakan sintaks seperti ini:
Dan inilah dokumentasi untuk diterapkan , dan ditugaskan .
sumber
SettingWithCopyWarning
ketika saya melakukannyadf['c'] = df.apply(lambda row: row.a + row.b, axis=1)
Apakah itu masalah nyata di sini, atau haruskah saya tidak mengkhawatirkannya?Jawaban di atas benar-benar valid, tetapi ada solusi vektor, dalam bentuk
numpy.select
. Ini memungkinkan Anda untuk menentukan kondisi, lalu menentukan keluaran untuk kondisi tersebut, jauh lebih efisien daripada menggunakanapply
:Pertama, tentukan kondisi:
Sekarang, tentukan output yang sesuai:
Akhirnya, menggunakan
numpy.select
:Kenapa harus
numpy.select
digunakan berlebihanapply
? Berikut ini beberapa pemeriksaan kinerja:Menggunakan
numpy.select
memberi kami kinerja yang jauh lebih baik, dan perbedaan hanya akan meningkat ketika data bertambah.sumber
.apply()
mengambil fungsi sebagai parameter pertama; operasikanlabel_race
fungsi sebagai berikut:Anda tidak perlu membuat fungsi lambda untuk lulus dalam suatu fungsi.
sumber
coba ini,
O / P:
gunakan
.loc
sebagai gantiapply
.itu meningkatkan vektorisasi.
.loc
bekerja dengan cara sederhana, mask baris berdasarkan kondisi, terapkan nilai pada baris beku.untuk lebih jelasnya kunjungi, .loc docs
Metrik kinerja:
Jawaban yang diterima:
Jawaban Usulan Saya:
sumber