Saya memiliki kerangka data panda dengan kolom tipe campuran, dan saya ingin menerapkan min_max_scaler sklearn ke beberapa kolom. Idealnya, saya ingin melakukan transformasi ini di tempat, tetapi belum menemukan cara untuk melakukan itu. Saya telah menulis kode berikut yang berfungsi:
import pandas as pd
import numpy as np
from sklearn import preprocessing
scaler = preprocessing.MinMaxScaler()
dfTest = pd.DataFrame({'A':[14.00,90.20,90.95,96.27,91.21],'B':[103.02,107.26,110.35,114.23,114.68], 'C':['big','small','big','small','small']})
min_max_scaler = preprocessing.MinMaxScaler()
def scaleColumns(df, cols_to_scale):
for col in cols_to_scale:
df[col] = pd.DataFrame(min_max_scaler.fit_transform(pd.DataFrame(dfTest[col])),columns=[col])
return df
dfTest
A B C
0 14.00 103.02 big
1 90.20 107.26 small
2 90.95 110.35 big
3 96.27 114.23 small
4 91.21 114.68 small
scaled_df = scaleColumns(dfTest,['A','B'])
scaled_df
A B C
0 0.000000 0.000000 big
1 0.926219 0.363636 small
2 0.935335 0.628645 big
3 1.000000 0.961407 small
4 0.938495 1.000000 small
Saya ingin tahu apakah ini adalah cara yang disukai / paling efisien untuk melakukan transformasi ini. Apakah ada cara saya bisa menggunakan df.apply itu akan lebih baik?
Saya juga terkejut saya tidak bisa mendapatkan kode berikut untuk bekerja:
bad_output = min_max_scaler.fit_transform(dfTest['A'])
Jika saya meneruskan seluruh dataframe ke scaler itu berfungsi:
dfTest2 = dfTest.drop('C', axis = 1)
good_output = min_max_scaler.fit_transform(dfTest2)
good_output
Saya bingung mengapa melewatkan seri ke scaler gagal. Dalam kode kerja lengkap saya di atas, saya berharap hanya meneruskan seri ke scaler kemudian mengatur kolom dataframe = ke seri yang diskalakan. Saya telah melihat pertanyaan ini menanyakan beberapa tempat lain, tetapi belum menemukan jawaban yang baik. Bantuan apa pun yang memahami apa yang terjadi di sini akan sangat dihargai!
sumber
bad_output = min_max_scaler.fit_transform(dfTest['A'].values)
? mengaksesvalues
atribut mengembalikan array numpy, untuk beberapa alasan terkadang scikit learn api akan memanggil metode yang benar yang membuat panda mengembalikan array numpy dan terkadang tidak.bad_output = in_max_scaler.fit_transform(dfTest['A'].values)
juga tidak berfungsi. @ Larsmans - ya saya sudah berpikir tentang turun rute ini, sepertinya merepotkan. Saya tidak tahu apakah ini bug atau tidak bahwa Pandas dapat meneruskan kerangka data lengkap ke fungsi sklearn, tetapi bukan seri. Pemahaman saya tentang sebuah dataframe adalah bahwa itu adalah dict of series. Membaca dalam buku "Python untuk Analisis Data", ia menyatakan bahwa panda dibangun di atas numpy untuk membuatnya mudah digunakan dalam aplikasi NumPy-centric.Jawaban:
Saya tidak yakin apakah versi sebelumnya
pandas
mencegah ini tetapi sekarang cuplikan berikut ini berfungsi dengan baik untuk saya dan menghasilkan apa yang Anda inginkan tanpa harus menggunakanapply
sumber
df[df.columns] = scaler.fit_transform(df[df.columns])
__getitem__
metode ini. Secara khusus Anda dapat membuka ipython Anda dan melakukannyapd.DataFrame.__getitem__??
; setelah Anda mengimpor panda sebagai pd tentu saja;)columns =df.columns.drop('timestamps') df[df.columns] = scaler.fit_transform(df[df.columns]
Seperti ini?
sumber
Seperti yang disebutkan dalam komentar pir -
.apply(lambda el: scale.fit_transform(el))
metode ini akan menghasilkan peringatan berikut:Mengubah kolom Anda menjadi array numpy harus melakukan pekerjaan (saya lebih suka StandardScaler):
- Edit Nov 2018 (Diuji untuk panda 0.23.4 ) -Seperti yang dikatakan Rob Murray dalam komentar, dalam versi panda saat ini (v0.23.4)
.as_matrix()
kembaliFutureWarning
. Karena itu, harus diganti dengan.values
:- Edit Mei 2019 (Diuji untuk panda 0.24.2 ) -
Seperti yang disebutkan joelostblom dalam komentar, "Karena
0.24.0
, disarankan untuk menggunakan.to_numpy()
daripada.values
."Contoh yang diperbarui:
sumber
.values
di tempat.as_matrix()
sepertias_matrix()
sekarang memberi aFutureWarning
.0.24.0
, disarankan untuk menggunakan.to_numpy()
daripada.values
.Ini harus bekerja tanpa peringatan penyusutan.
sumber
Anda dapat melakukannya
pandas
hanya dengan menggunakan :sumber
df.max() - df.min()
bisa 0, yang mengarah ke pengecualian. Selain itu,df.min()
dihitung dua kali yang tidak efisien. Catatan yangdf.ptp()
setara dengandf.max() - df.min()
.Saya tahu ini komentar yang sangat lama, tapi tetap saja:
Alih-alih menggunakan braket tunggal
(dfTest['A'])
, gunakan tanda kurung ganda(dfTest[['A']])
.yaitu:
min_max_scaler.fit_transform(dfTest[['A']])
.Saya yakin ini akan memberikan hasil yang diinginkan.
sumber