Penugasan kolom super sederhana
Rangka data panda diimplementasikan sebagai dict kolom yang dipesan.
Ini berarti bahwa __getitem__
[]
tidak hanya dapat digunakan untuk mendapatkan kolom tertentu, tetapi __setitem__
[] =
dapat digunakan untuk menetapkan kolom baru.
Misalnya, kerangka data ini dapat memiliki kolom yang ditambahkan padanya hanya dengan menggunakan []
accessor
size name color
0 big rose red
1 small violet blue
2 small tulip red
3 small harebell blue
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
Perhatikan bahwa ini berfungsi bahkan jika indeks bingkai data tidak aktif.
df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
[] = adalah cara untuk pergi, tapi hati-hati!
Namun, jika Anda memiliki pd.Series
dan mencoba untuk menetapkannya ke kerangka data di mana indeks tidak aktif, Anda akan mengalami masalah. Lihat contoh:
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
Ini karena secara pd.Series
default memiliki indeks yang dihitung dari 0 hingga n. Dan [] =
metode panda mencoba menjadi "pintar"
Apa yang sebenarnya terjadi.
Ketika Anda menggunakan [] =
metode panda diam-diam melakukan gabungan luar atau gabungan luar menggunakan indeks kerangka data tangan kiri dan indeks seri tangan kanan.df['column'] = series
Catatan samping
Ini dengan cepat menyebabkan disonansi kognitif, karena []=
metode ini mencoba melakukan banyak hal berbeda tergantung pada input, dan hasilnya tidak dapat diprediksi kecuali Anda hanya tahu cara kerja panda. Karena itu saya akan menyarankan terhadap[]=
basis kode, tetapi ketika mengeksplorasi data dalam notebook, itu baik-baik saja.
Mengatasi masalah
Jika Anda memiliki pd.Series
dan menginginkannya ditetapkan dari atas ke bawah, atau jika Anda mengkode kode produktif dan Anda tidak yakin dengan urutan indeks, Anda layak untuk melindungi untuk masalah seperti ini.
Anda bisa downcast pd.Series
ke np.ndarray
atau list
, ini akan melakukan trik.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values
atau
df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))
Tetapi ini tidak terlalu eksplisit.
Beberapa coder mungkin datang dan berkata "Hei, ini terlihat berlebihan, saya hanya akan mengoptimalkan ini saja".
Cara eksplisit
Pengaturan indeks pd.Series
menjadi indeks df
eksplisit.
df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)
Atau lebih realistis, Anda mungkin sudah memiliki pd.Series
.
protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index
3 no
2 no
1 no
0 yes
Sekarang bisa ditugaskan
df['protected'] = protected_series
size name color protected
3 big rose red no
2 small violet blue no
1 small tulip red no
0 small harebell blue yes
Cara alternatif dengan df.reset_index()
Karena disonansi indeks adalah masalahnya, jika Anda merasa bahwa indeks dari kerangka data tidak boleh menentukan hal-hal, Anda dapat dengan mudah menjatuhkan indeks, ini harus lebih cepat, tetapi itu tidak terlalu bersih, karena fungsi Anda sekarang mungkin melakukan dua hal.
df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series
size name color protected
0 big rose red no
1 small violet blue no
2 small tulip red no
3 small harebell blue yes
Catatan aktif df.assign
Sementara df.assign
membuatnya lebih eksplisit apa yang Anda lakukan, sebenarnya memiliki semua masalah yang sama seperti di atas[]=
df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
size name color protected
3 big rose red yes
2 small violet blue no
1 small tulip red no
0 small harebell blue no
Berhati-hatilah dengan df.assign
kolom Anda yang tidak dipanggil self
. Itu akan menyebabkan kesalahan. Ini membuat df.assign
bau , karena ada jenis artefak dalam fungsinya.
df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'
Anda mungkin berkata, "Baiklah, saya tidak akan menggunakannya self
". Tapi siapa yang tahu bagaimana fungsi ini berubah di masa depan untuk mendukung argumen baru. Mungkin nama kolom Anda akan menjadi argumen dalam pembaruan panda baru, yang menyebabkan masalah dengan peningkatan.