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.

Hitam
sumber

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.

BrenBarn
sumber
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
Jimmy Petersson
sumber
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>]
44
w.female.replace(to_replace=dict(female=1, male=0), inplace=True)

Lihat dokumen pandas.DataFrame.replace () .

jfs
sumber
Ini adalah solusi terbaik untuk masalah yang saya alami, terima kasih!
Andrew Brēza
40

Variasi kecil:

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

Ini juga harus bekerja:

w.female[w.female == 'female'] = 1 
w.female[w.female == 'male']   = 0
Nick Crawford
sumber
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.

siswa
sumber
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)
Azz
sumber
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.

galliwuzz.dll
sumber
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
Erfan
sumber
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.

Roald
sumber
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.

AD Alex-droid
sumber
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.

ebuitragod.dll
sumber