Mengganti nilai kolom dalam DataFrame pandas


149

Saya mencoba untuk mengganti nilai dalam satu kolom dataframe. Kolom ('female') hanya berisi nilai 'female' dan 'male'.

Saya telah mencoba yang berikut ini:

w['female']['female']='1'
w['female']['male']='0' 

Tetapi menerima salinan yang sama persis dari hasil sebelumnya.

Idealnya saya ingin mendapatkan beberapa output yang menyerupai elemen loop berikut-bijaksana.

if w['female'] =='female':
    w['female'] = '1';
else:
    w['female'] = '0';

Saya telah memeriksa dokumentasi gotchas ( http://pandas.pydata.org/pandas-docs/stable/gotchas.html ) tetapi tidak dapat menemukan mengapa tidak terjadi apa-apa.

Bantuan apa pun akan dihargai.

Jawaban:


273

Jika saya mengerti benar, Anda menginginkan yang seperti ini:

w['female'] = w['female'].map({'female': 1, 'male': 0})

(Di sini saya mengonversi nilai menjadi angka alih-alih string yang berisi angka. Anda dapat mengonversinya menjadi "1"dan "0", jika Anda benar-benar menginginkannya, tetapi saya tidak yakin mengapa Anda menginginkannya.)

Alasan kode Anda tidak berfungsi adalah karena menggunakan ['female']pada kolom (yang kedua 'female'di Anda w['female']['female']) tidak berarti "pilih baris yang nilainya 'perempuan'". Ini berarti memilih baris yang indeksnya adalah 'perempuan', yang mungkin tidak ada di DataFrame Anda.


6
Terima kasih. Persis apa yang saya cari. Jika saya memetakan 'wanita' ke 1 dan yang lainnya ke '0'. Bagaimana cara kerjanya?
Hitam

19
gunakan ini saja, jika semua nilai dalam kolom diberikan dalam fungsi peta. Nilai kolom yang tidak ditentukan dalam fungsi peta akan diganti dengan nan.
Chandra

1
Saya juga merekomendasikan penggunaan .locsintaks untuk menghindari SettingWithCopyWarning: pandas.pydata.org/pandas-docs/stable/…
NickBraunagel

2
alih-alih .map saya menggunakan .replace
JS noob

Bagaimana cara menghilangkan '.' dari ribuan di dua atau lebih kolom, tidak bisa mengerti. terima kasih banyak
M. Mariscal

123

Anda dapat mengedit subset dataframe dengan menggunakan loc:

df.loc[<row selection>, <column selection>]

Pada kasus ini:

w.loc[w.female != 'female', 'female'] = 0
w.loc[w.female == 'female', 'female'] = 1

1
Bagaimana cara saya menyesuaikannya sehingga saya tidak perlu memilih baris tertentu melalui kondisi, hanya semua baris di kolom tertentu? Jadi ubah semua sel dalam kolom ke nilai tertentu.
Dhruv Ghulati

3
@DhruvGhulati, Anda akan menggunakan df.loc [:, <column selection>]


40

Variasi kecil:

w.female.replace(['male', 'female'], [1, 0], inplace=True)

21

Ini juga harus bekerja:

w.female[w.female == 'female'] = 1 
w.female[w.female == 'male']   = 0

13

Anda juga dapat menggunakan applydengan .getie

w['female'] = w['female'].apply({'male':0, 'female':1}.get):

w = pd.DataFrame({'female':['female','male','female']})
print(w)

Dataframe w:

   female
0  female
1    male
2  female

Menggunakan applyuntuk mengganti nilai dari kamus:

w['female'] = w['female'].apply({'male':0, 'female':1}.get)
print(w)

Hasil:

   female
0       1
1       0
2       1 

Catatan: apply with dictionary harus digunakan jika semua nilai yang mungkin dari kolom dalam dataframe didefinisikan dalam kamus lain, itu akan kosong untuk yang tidak didefinisikan dalam kamus.


10

Ini sangat kompak:

w['female'][w['female'] == 'female']=1
w['female'][w['female'] == 'male']=0

Satu lagi bagus:

w['female'] = w['female'].replace(regex='female', value=1)
w['female'] = w['female'].replace(regex='male', value=0)

Contoh pertama adalah pengindeksan berantai dan diperingatkan karena tidak dapat menjamin apakah df yang dihasilkan adalah salinan atau tampilan. Lihat pengindeksan
berantai

8

Sebagai alternatif, ada fungsi built-in pd.get_dummies untuk jenis tugas ini:

w['female'] = pd.get_dummies(w['female'],drop_first = True)

Ini memberi Anda bingkai data dengan dua kolom, satu untuk setiap nilai yang terjadi di w ['female'], di mana Anda melepaskan yang pertama (karena Anda dapat menyimpulkannya dari yang tersisa). Kolom baru secara otomatis dinamai sebagai string yang Anda ganti.

Ini sangat berguna jika Anda memiliki variabel kategori dengan lebih dari dua kemungkinan nilai. Fungsi ini membuat sebanyak mungkin variabel dummy yang diperlukan untuk membedakan semua kasus. Berhati-hatilah agar Anda tidak menetapkan keseluruhan frame data ke satu kolom, tetapi sebaliknya, jika w ['female'] bisa jadi 'male', 'female' atau 'neutral', lakukan sesuatu seperti ini:

w = pd.concat([w, pd.get_dummies(w['female'], drop_first = True)], axis = 1])
w.drop('female', axis = 1, inplace = True)

Kemudian Anda memiliki dua kolom baru yang memberi Anda kode dummy 'perempuan' dan Anda menyingkirkan kolom dengan string.


5

Menggunakan Series.mapdenganSeries.fillna

Jika kolom Anda berisi lebih banyak string daripada femaledan male, Series.mapakan gagal dalam kasus ini karena akan mengembalikan NaNnilai lain.

Itu sebabnya kami harus merantai dengan fillna:

Contoh mengapa .mapgagal :

df = pd.DataFrame({'female':['male', 'female', 'female', 'male', 'other', 'other']})

   female
0    male
1  female
2  female
3    male
4   other
5   other
df['female'].map({'female': '1', 'male': '0'})

0      0
1      1
2      1
3      0
4    NaN
5    NaN
Name: female, dtype: object

Untuk metode yang benar , kita rantai mapdengan fillna, jadi kita isi NaNdengan nilai dari kolom asli:

df['female'].map({'female': '1', 'male': '0'}).fillna(df['female'])

0        0
1        1
2        1
3        0
4    other
5    other
Name: female, dtype: object

2

Ada juga fungsi di pandaspanggil factorizeyang dapat Anda gunakan untuk melakukan jenis pekerjaan ini secara otomatis. Itu mengkonversi label untuk nomor: ['male', 'female', 'male'] -> [0, 1, 0]. Lihat jawaban ini untuk informasi lebih lanjut.


0

Saya pikir sebagai jawaban harus ditunjukkan jenis objek yang Anda dapatkan di semua metode yang disarankan di atas: apakah itu Seri atau DataFrame.

Ketika Anda mendapatkan kolom dengan w.female.atau w[[2]](di mana, misalkan, 2 adalah nomor kolom Anda), Anda akan mendapatkan kembali DataFrame. Jadi dalam hal ini Anda dapat menggunakan metode DataFrame seperti .replace.

Ketika Anda menggunakan .locatau ilocAnda mendapatkan kembali Seri, dan Seri tidak memiliki .replacemetode, jadi Anda harus menggunakan metode seperti apply, mapdan seterusnya.


0
dic = {'female':1, 'male':0}
w['female'] = w['female'].replace(dic)

.replace memiliki argumen kamus di mana Anda dapat mengubah dan melakukan apa pun yang Anda inginkan atau butuhkan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.