Panda dataframe'inde normalizasyon nasıl yapılır?

Bazı değişkenleri analiz ederken normalizasyon yapmak önemlidir. Örnek olarak fiyat ve m2. Fiyat binlerle ifade edilirken m2 yüzler ölçeğindedir. Uzaklık mesafeside yine km olarak farklı bir ölçektedir. Bu 3 değeri birbiri ile ölçerken veya birbiri arasında yakınlık ölçerken normalizasyon ile [0,1] arasına çekilmelidir.
Bu yazımımızda aşağıdaki iki normalizasyon denklemini kullanacağız.
1) (max(x)-x)/(max(x))
2) (x-min(x))/(max(x)-min(x))

Gerekli paketleri öncelikle yükleyelim

In [1]:
import pandas as pd # Panda dataframe'i icin gerekli
from pandas import DataFrame 
import warnings
warnings.filterwarnings('ignore')

Dataframe'mimiz aşağıdadır.Group_Id ile Group_Id1 arasındaki prize,size ve distance'ı normalize edelim.

In [11]:
 data = [['1020',12000,100,'1060',15000,120,1.2],
         ['1020',12000,100,'1050',20000,75,0.9],
         ['1020',12000,100,'1030',10000,90,2.3],
         ['1030',5000,150,'1040',10000,300,3.7],
         ['1030',5000,150,'1080',2500,60,0.3]]
df = pd.DataFrame(data, columns = ['Group_Id', 'Price','Size','Group_Id1', 'Price1','Size1','distance']) 
  
# print dataframe. 
df
Out[11]:
Group_Id Price Size Group_Id1 Price1 Size1 distance
0 1020 12000 100 1060 15000 120 1.2
1 1020 12000 100 1050 20000 75 0.9
2 1020 12000 100 1030 10000 90 2.3
3 1030 5000 150 1040 10000 300 3.7
4 1030 5000 150 1080 2500 60 0.3

Öncelikle Group_Id bazında Price1 ve Size1'in ortalamalarını kontrol edelim

In [12]:
df_avg=df.groupby('Group_Id',as_index=False).agg({'Price1' : 'mean', 'Size1' : 'mean', 'distance': 'mean'})
df_avg.columns = ['Group_Id', 'Price_mean', 'Size_mean','distance_mean']
df_avg.head(10)
Out[12]:
Group_Id Price_mean Size_mean distance_mean
0 1020 15000 95 1.466667
1 1030 6250 180 2.000000

Price'ın ve Size'ın farklarını alalım. Distance iki item arasında ki fark olduğundan farkı alınmadı

In [13]:
df['Price_dif'] = (df['Price'] - df['Price1']).abs()
df['size_dif'] = (df['Size'] -df['Size1']).abs()
df.head(10)
Out[13]:
Group_Id Price Size Group_Id1 Price1 Size1 distance Price_dif size_dif
0 1020 12000 100 1060 15000 120 1.2 3000 20
1 1020 12000 100 1050 20000 75 0.9 8000 25
2 1020 12000 100 1030 10000 90 2.3 2000 10
3 1030 5000 150 1040 10000 300 3.7 5000 150
4 1030 5000 150 1080 2500 60 0.3 2500 90

Price_dif ve size_dif üzerine x-min(x))/(max(x)-min(x))) formulü group_id bazında uygulanmıştır.

In [14]:
df_score=df[['Group_Id','Price_dif','size_dif','distance']]
df_score[['Price_dif_score', 'Size_dif_score','distance_score']]= df_score.groupby('Group_Id')\
    .transform(lambda x: (x-x.min())/(x.max()-x.min()))
df_score.head()
Out[14]:
Group_Id Price_dif size_dif distance Price_dif_score Size_dif_score distance_score
0 1020 3000 20 1.2 0.166667 0.666667 0.214286
1 1020 8000 25 0.9 1.000000 1.000000 0.000000
2 1020 2000 10 2.3 0.000000 0.000000 1.000000
3 1030 5000 150 3.7 1.000000 1.000000 1.000000
4 1030 2500 90 0.3 0.000000 0.000000 0.000000

Asağıda apply fonksiyonu kullanaraktan normalizasyon yapılmıştır.

In [15]:
cols = ['Price_dif','size_dif','distance']
df[cols] = df.groupby('Group_Id')[cols].apply(lambda x: (x-x.min())/(x.max()-x.min()))
df.head()
Out[15]:
Group_Id Price Size Group_Id1 Price1 Size1 distance Price_dif size_dif
0 1020 12000 100 1060 15000 120 0.214286 0.166667 0.666667
1 1020 12000 100 1050 20000 75 0.000000 1.000000 1.000000
2 1020 12000 100 1030 10000 90 1.000000 0.000000 0.000000
3 1030 5000 150 1040 10000 300 1.000000 1.000000 1.000000
4 1030 5000 150 1080 2500 60 0.000000 0.000000 0.000000

Aşağıda farklı bir yolla normalizasyon yapılmıştır

In [16]:
df_score=df[['Group_Id','Price_dif','size_dif','distance']]
dist =  df_score.groupby('Group_Id').transform('max')
df_score1 = df_score.join(dist.sub(df_score.drop('Group_Id', axis=1)).div(dist).add_suffix('_score'))\
            .drop(['Price_dif','size_dif','distance'], axis=1)
df_score1.head()
Out[16]:
Group_Id Price_dif_score size_dif_score distance_score
0 1020 0.833333 0.333333 0.785714
1 1020 0.000000 0.000000 1.000000
2 1020 1.000000 1.000000 0.000000
3 1030 0.000000 0.000000 0.000000
4 1030 1.000000 1.000000 1.000000

Aşağıda Group bazında normalizasyon yapılmıştır ve kullanılan formül (x-min(x))/(max(x)-min(x))'dir

In [25]:
data = [['Group 1',10,100],
       ['Group 1',28,80],
       ['Group 1',15,60],
       ['Group 1',30,120],
       ['Group 2',10,120],
       ['Group 2',20,130],
       ['Group 2',30,200],
       ['Group 2',40,250],
       ['Group 2',50,300]] 
df = pd.DataFrame(data, columns = ['Group','price','size']) 
In [24]:
df[['normalized_price', 'normalized_size']]= df.groupby('Group').transform(lambda x: (x - x.min())/ (x.max() - x.min()))
df
Out[24]:
Group price size normalized_price normalized_size
0 Group 1 10 100 0.00 0.666667
1 Group 1 28 80 0.90 0.333333
2 Group 1 15 60 0.25 0.000000
3 Group 1 30 120 1.00 1.000000
4 Group 2 10 120 0.00 0.000000
5 Group 2 20 130 0.25 0.055556
6 Group 2 30 200 0.50 0.444444
7 Group 2 40 250 0.75 0.722222
8 Group 2 50 300 1.00 1.000000
In [26]:
df[['normalized_price', 'normalized_size']]= df.groupby('Group').transform(lambda x: (x.max() - x)/ x.max())
df
Out[26]:
Group price size normalized_price normalized_size
0 Group 1 10 100 0.666667 0.166667
1 Group 1 28 80 0.066667 0.333333
2 Group 1 15 60 0.500000 0.500000
3 Group 1 30 120 0.000000 0.000000
4 Group 2 10 120 0.800000 0.600000
5 Group 2 20 130 0.600000 0.566667
6 Group 2 30 200 0.400000 0.333333
7 Group 2 40 250 0.200000 0.166667
8 Group 2 50 300 0.000000 0.000000