pandas數據預處理(標准化&歸一化、離散化/分箱/分桶、分類數據處理、時間類型數據處理、樣本類別分布不均衡數據處理、數據抽樣)

IT之一小佬 2022-01-07 15:44:52 阅读数:770

pandas 分箱 分布 不均 均衡

1. 數值型數據的處理

1.1 標准化&歸一化

        數據標准化是一個常用的數據預處理操作,目的是處理不同規模和量綱的數據,使其縮放到相同的數據區間和範圍,以减少規模、特征、分布差异等對模型的影響。

示例代碼:

import numpy as np
from sklearn import preprocessing
import matplotlib.pyplot as plt
data = np.loadtxt('../data/excel_data/data6.txt', delimiter='\t') # 讀取數據
data

# Z-Score標准化
zscore_scaler = preprocessing.StandardScaler() # 建立StandardScaler對象
data_scale_1 = zscore_scaler.fit_transform(data) # StandardScaler標准化處理
data_scale_1

# 歸一化Max-Min
minmax_scaler = preprocessing.MinMaxScaler() # 建立MinMaxScaler模型對象
data_scale_2 = minmax_scaler.fit_transform(data) # MinMaxScaler標准化處理
data_scale_2

# 展示多網絡結果
data_list = [data, data_scale_1, data_scale_2] # 創建數據集列錶
color_list = ['black', 'green', 'blue'] # 創建顏色列錶
merker_list = ['o', ',','+'] # 創建樣式列錶
title_list = ['source data', 'zscore_scaler', 'minmax_scaler'] # 創建標題列錶
plt.figure(figsize=(13, 3))
for i, data_single in enumerate(data_list): # 循環得到索引和每個數值
plt.subplot(1, 3, i + 1) # 確定子網格
plt.scatter(data_single[:, :-1], data_single[:, -1], s=10, marker=merker_list[i], c=color_list[i]) # 子網格展示散點圖
plt.title(title_list[i]) # 設置子網格標題
plt.suptitle("raw data and standardized data") # 設置總標題 

1.2. 離散化/分箱/分桶

import pandas as pd
from sklearn.cluster import KMeans
from sklearn import preprocessing
# 讀取數據
df = pd.read_table('../data/excel_data/data7.txt', names=['id', 'amount', 'income', 'datetime', 'age']) # 讀取數據文件
df.head(5) # 打印輸出前5條數據

# 針對時間數據的離散化
df['datetime'] = list(map(pd.to_datetime,df['datetime'])) # 將時間轉換為datetime格式
df['datetime'] = [i.weekday() for i in df['datetime']]# 離散化為周幾
df.head(5) # 打印輸出前5條數據

# 針對連續數據的離散化:自定義分箱區間實現離散化
bins = [0, 200, 1000, 5000, 10000] # 自定義區間邊界
df['amount1'] = pd.cut(df['amount'], bins) # 使用邊界做離散化
df.head(5) # 打印輸出前5條數據

# 針對連續數據的離散化:使用聚類法實現離散化
data = df['amount'] # 獲取要聚類的數據,名為amount的列
data_reshape = data.values.reshape((data.shape[0], 1)) # 轉換數據形狀
model_kmeans = KMeans(n_clusters=4, random_state=0) # 創建KMeans模型並指定要聚類數量
keames_result = model_kmeans.fit_predict(data_reshape) # 建模聚類
df['amount2'] = keames_result # 新離散化的數據合並到原數據框
df.head(5) # 打印輸出前5條數據

# 針對連續數據的離散化
df['amount3'] = pd.qcut(df['amount'], 4, labels=['bad', 'medium', 'good', 'awesome'])
df = df.drop('amount', 1) # 丟弃名為amount的列
df.head(5) # 打印輸出前5條數據

# 針對連續數據的二值化
binarizer_scaler = preprocessing.Binarizer(threshold=df['income'].mean()) # 建立Binarizer模型對象
income_tmp = binarizer_scaler.fit_transform(df[['income']]) # Binarizer標准化轉換
income_tmp.resize(df['income'].shape) # 轉換數據形狀
df['income'] = income_tmp # Binarizer標准化轉換
df.head(5) # 打印輸出前5條數據 

2. 分類數據的處理

舉例:

  • 性別中的男和女 [0,1] [1,0]
  • 顏色中的紅、黃和藍
  • 用戶的價值度分為高、中、低
  • 學曆分為博士、碩士、學士、大專、高中

處理方法:

  • 將字符串錶示的分類特征轉換成數值類型,一般用one-hot編碼錶示,方便建模處理

示例代碼:

import pandas as pd # 導入pandas庫
from sklearn.preprocessing import OneHotEncoder # 導入庫
# 生成數據
df = pd.DataFrame({'id': [3566841, 6541227, 3512441],
'sex': ['male', 'Female', 'Female'],
'level': ['high', 'low', 'middle'],
'score': [1, 2, 3]})
df # 打印輸出原始數據框

# 使用sklearn進行標志轉換
# 拆分ID和數據列
id_data = df[['id']] # 獲得ID列
raw_convert_data = df.iloc[:, 1:] # 指定要轉換的列
raw_convert_data

# 將數值型分類向量轉換為標志變量
model_enc = OneHotEncoder() # 建立標志轉換模型對象(也稱為啞編碼對象)
df_new2 = model_enc.fit_transform(raw_convert_data).toarray() # 標志轉換
df_new2

# 合並數據
df_all = pd.concat((id_data, pd.DataFrame(df_new2)), axis=1) # 重新組合為數據框
df_all # 打印輸出轉換後的數據框

# 使用pandas的get_dummuies ,此方法只會對非數值類型的數據做轉換
df_new3 = pd.get_dummies(raw_convert_data)
df_all2 = pd.concat((id_data, df_new3), axis=1) # 重新組合為數據框
df_all2 # 打印輸出轉換後的數據框

 3. 時間類型數據的處理

        數據中包含日期時間類型的數據可以通過pandas的 to_datetime 轉換成datetime類型,方便提取各種時間信息。

示例代碼:

import pandas as pd
car_sales = pd.read_csv('../data/excel_data/car_data.csv')
car_sales.head()

car_sales.loc[:,'date'] = pd.to_datetime(car_sales['date_t'])
car_sales

 

# 取出關鍵時間信息
# 取出幾月份
car_sales.loc[:,'month'] = car_sales['date'].dt.month
# 取出來是幾號
car_sales.loc[:,'dom'] = car_sales['date'].dt.day
# 取出一年當中的第幾天
car_sales.loc[:,'doy'] = car_sales['date'].dt.dayofyear
# 取出星期幾
car_sales.loc[:,'dow'] = car_sales['date'].dt.dayofweek
car_sales.head()

4.  樣本類別分布不均衡數據處理

示例代碼:

import pandas as pd
from imblearn.over_sampling import SMOTE # 過抽樣處理庫SMOTE
from imblearn.under_sampling import RandomUnderSampler # 欠抽樣處理庫RandomUnderSampler
# 導入數據文件
df = pd.read_table('../data/excel_data/data2.txt', sep='\t', names=['col1', 'col2', 'col3', 'col4', 'col5', 'label']) # 讀取數據文件
x, y = df.iloc[:, :-1],df.iloc[:, -1] # 切片,得到輸入x,標簽y
groupby_data_orgianl = df.groupby('label').count() # 對label做分類匯總
groupby_data_orgianl # 打印輸出原始數據集樣本分類分布

# 使用SMOTE方法進行過抽樣處理
model_smote = SMOTE() # 建立SMOTE模型對象
x_smote_resampled, y_smote_resampled = model_smote.fit_resample(x, y) # 輸入數據並作過抽樣處理
x_smote_resampled = pd.DataFrame(x_smote_resampled, columns=['col1', 'col2', 'col3', 'col4', 'col5']) # 將數據轉換為數據框並命名列名
y_smote_resampled = pd.DataFrame(y_smote_resampled, columns=['label']) # 將數據轉換為數據框並命名列名
smote_resampled = pd.concat([x_smote_resampled, y_smote_resampled], axis=1) # 按列合並數據框
groupby_data_smote = smote_resampled.groupby('label').count() # 對label做分類匯總
groupby_data_smote # 打印輸出經過SMOTE處理後的數據集樣本分類分布

# 使用RandomUnderSampler方法進行欠抽樣處理
model_RandomUnderSampler = RandomUnderSampler() # 建立RandomUnderSampler模型對象
x_RandomUnderSampler_resampled, y_RandomUnderSampler_resampled = model_RandomUnderSampler.fit_resample(x, y) # 輸入數據並作欠抽樣處理
x_RandomUnderSampler_resampled = pd.DataFrame(x_RandomUnderSampler_resampled,
columns=['col1', 'col2', 'col3', 'col4', 'col5']) # 將數據轉換為數據框並命名列名
y_RandomUnderSampler_resampled = pd.DataFrame(y_RandomUnderSampler_resampled,
columns=['label']) # 將數據轉換為數據框並命名列名
RandomUnderSampler_resampled = pd.concat([x_RandomUnderSampler_resampled, y_RandomUnderSampler_resampled],axis=1) # 按列合並數據框
groupby_data_RandomUnderSampler = RandomUnderSampler_resampled.groupby('label').count() # 對label做分類匯總
groupby_data_RandomUnderSampler # 打印輸出經過RandomUnderSampler處理後的數據集樣本分類分布

5.  數據抽樣

示例代碼:

import random # 導入標准庫
import numpy as np # 導入第三方庫
data = np.loadtxt('../data/excel_data/data3.txt') # 導入普通數據文件
shuffle_index = np.random.choice(np.arange(data.shape[0]),2000,True)#隨機生成200個行號
data_sample = data[shuffle_index] #從原始數據中取出200個行號對應的數據
print(len(data_sample)) # 打印輸出抽樣樣本量
data_sample[:2] # 打印輸出前2條數據

# 等距抽樣
data = np.loadtxt('../data/excel_data/data3.txt') # 導入普通數據文件
sample_count = 2000 # 指定抽樣數量
record_count = data.shape[0] # 獲取最大樣本量
width = record_count / sample_count # 計算抽樣間距
data_sample = [] # 初始化空白列錶,用來存放抽樣結果數據
i = 0 # 自增計數以得到對應索引值
while len(data_sample) <= sample_count and i * width <= record_count - 1: # 當樣本量小於等於指定抽樣數量並且矩陣索引在有效範圍內時
data_sample.append(data[int(i * width)]) # 新增樣本
i += 1 # 自增長
print(len(data_sample)) # 打印輸出樣本數量
data_sample[:2] # 打印輸出前2條數據

版权声明:本文为[IT之一小佬]所创,转载请带上原文链接,感谢。 https://gsmany.com/2022/01/202201071544519625.html