一、什么是數據預處理
數據預處理(Data Preprocessing)是數據分析和機器學習中至關重要的步驟,旨在將原始數據轉換為更高質量、更適合分析或建模的形式。由于真實世界的數據通常存在不完整、不一致、噪聲或冗余等問題,預處理可以幫助提高數據的可用性和模型的性能。
數據預處理的主要步驟
-
數據清洗(Data Cleaning)
-
處理缺失值:填充(均值、中位數、眾數等)、刪除缺失樣本或字段。
-
處理噪聲數據:平滑或剔除異常值(如使用分箱、聚類或統計方法)。
-
糾正不一致數據:統一格式(如日期格式、單位)、修正邏輯錯誤。
-
-
數據集成(Data Integration)
-
合并多個數據源,解決冗余、沖突或重復問題(例如同名不同義的字段)。
-
-
數據變換(Data Transformation)
-
標準化(Standardization):將數據縮放到均值為0、標準差為1(如Z-score)。
-
歸一化(Normalization):將數據縮放到固定范圍(如[0,1])。
-
離散化(Discretization):將連續數值分段(如年齡分為“青年”“中年”“老年”)。
-
特征編碼:將分類變量轉換為數值(如獨熱編碼、標簽編碼)。
-
-
數據歸約(Data Reduction)
-
降低數據規模,同時保留關鍵信息,例如:
-
特征選擇:篩選重要特征(如相關系數、隨機森林重要性)。
-
降維:使用主成分分析(PCA)、t-SNE等方法壓縮維度。
-
-
-
數據分箱(Binning)
-
將連續值劃分為區間,減少噪聲影響(如將收入分為“低、中、高”)。
-
數據預處理的目的
-
提高數據質量:消除噪聲、錯誤和不一致性。
-
提升模型性能:通過標準化、歸一化等手段優化數據分布。
-
減少計算成本:降維和歸約可加速模型訓練。
-
適配算法需求:許多算法對輸入數據的格式和范圍敏感(如神經網絡需要歸一化)。
舉例說明
-
原始數據問題:某用戶年齡字段包含“-1”(異常值),收入字段有缺失。
-
預處理后:刪除“-1”,用中位數填充缺失值,并對收入進行歸一化處理。
數據預處理是數據科學流程中不可或缺的環節,直接影響最終結果的可靠性和模型效果。
二、數據檢測
1.準備數據
2.查看NaN值
方法一:
isnull():是查看數據是否存在NaN值,如果有則返回True
方法二:
notnull():是查數據是否不存在NaN值,如果不存在則返回True
三、缺失值處理
1.查看缺失值的占比
2.提取出完整的數據
這里使用另外一組數據
3.清除全空值
dropna
?是 Pandas 中 DataFrame 的一個方法,用于刪除包含缺失值(NaN
)的行或列,目的是清理數據中的無效缺失信息。how
?是?dropna
?方法的一個參數,用于指定刪除行或列的條件:- 當?
how='any'
?時,只要行或列中?存在任意一個?NaN
,就刪除該行或列。 - 當?
how='all'
?時,僅當行或列中?所有值都為?NaN
?時,才刪除該行或列。
- 當?
4.篩選非空值數
5.某一列 = NaN,刪除整行數據
6.缺失值的替換處理
7.缺失值的填充處理
fillna
?是 Pandas 中 DataFrame 的一個方法,用于填充數據中的缺失值(NaN
),其常見屬性(參數)包括?value
(填充的具體值)、method
(填充方法)、axis
(指定軸,0
?或?'index'
?表示行,1
?或?'columns'
?表示列)等。method
?是?fillna
?方法的一個參數,用于指定填充缺失值的具體方法:'ffill'
(forward - fill
?的縮寫)表示向前填充,即用缺失值前面(按指定軸方向)的非缺失值來填充當前缺失值。例如,若按行方向(axis=0
),則用同一列中上方的非缺失值填充下方缺失值;若按列方向(axis=1
),則用同一行中前方的非缺失值填充后方缺失值。-
另一種常見值是?
'bfill'
(backward - fill
?的縮寫),表示向后填充,即用缺失值后面(按指定軸方向)的非缺失值來填充當前缺失值。
因為是向上填充,第一行已是最初數據,無法填充?
向下填充
四、重復值處理
1.查看重復值
2.刪除重復值數據
五、異常值處理
1.異常值替換
存在23和50替換成3和2
2.三西格瑪法則
three_sigma(df_obj['A'])
:對?df_obj
?數據框中的?'A'
?列應用?three_sigma
?函數,輸出為?6 30 Name: A, dtype: int64
,表明?'A'
?列中存在符合三西格瑪法則判定的異常值(這里顯示為?6
?和?30
)。
three_sigma(df_obj['B'])
:對?df_obj
?數據框中的?'B'
?列應用該函數,輸出為?Series([], Name: B, dtype: int64)
,表示?'B'
?列中沒有符合三西格瑪法則判定的異常值,返回一個空的 Series。
3.箱形圖檢測
六、數據合并
維度 | 橫向堆疊(列合并) | 縱向堆疊(行合并) |
---|---|---|
方向 | 左右擴展(新增列) | 上下擴展(新增行) |
核心操作 | JOIN (內連接、外連接等)、merge 、concat(axis=1) | UNION 、UNION ALL 、concat(axis=0) |
關鍵條件 | 需通過 “鍵” 對齊列(可能存在列名沖突) | 需列結構一致(列數、列名相同或可自動對齊) |
連接策略 | 外連接(橫向操作) | 內連接(橫向操作) |
---|---|---|
保留記錄 | 至少一個表的所有記錄,未匹配列填?NULL | 僅保留兩表連接鍵完全匹配的記錄 |
典型場景 | 保留所有數據(如客戶全量信息,無論是否有消費記錄) | 篩選交集數據(如同時存在于兩個表中的用戶) |
總結
- 橫向堆疊是列合并,外連接是橫向合并時保留非匹配記錄的策略;
- 縱向堆疊是行合并,與內連接無直接關聯(內連接屬于橫向合并的匹配策略)。
- 混淆點:內連接本質是橫向操作(列合并 + 篩選行),而縱向堆疊是單純的行追加,兩者分屬不同數據合并維度。
pd.concat(objs, # 需要合并的對象列表(DataFrame/Series)axis=0, # 合并方向:0=縱向(默認),1=橫向join='outer', # 連接方式:'outer'(默認)外連接(并集)或 'inner'內連接(交集)ignore_index=False, # 是否重置索引keys=None, # 創建多層索引sort=False, # 是否對列排序(axis=1 時)verify_integrity=False # 是否檢查重復索引
)
1.橫向堆疊與外連接(并集)
2.縱向堆疊與內連接(交集)
3.主鍵合并
pd.merge(left, # 左側 DataFrameright, # 右側 DataFramehow='inner', # 連接方式:'inner'(默認)、'outer'、'left'、'right'on=None, # 用于連接的列名(必須同時存在于左右 DataFrame 中)left_on=None, # 左側 DataFrame 中用于連接的列right_on=None, # 右側 DataFrame 中用于連接的列left_index=False, # 是否使用左側 DataFrame 的索引作為鍵right_index=False, # 是否使用右側 DataFrame 的索引作為鍵suffixes=('_x', '_y') # 用于區分重復列的后綴
)
與其他合并函數的對比
函數 | 核心特點 | 適用場景 |
---|---|---|
pd.merge() | 按鍵連接,支持多種連接類型(SQL 風格) | 基于共同列合并數據 |
pd.concat() | 按行 / 列堆疊,支持多層索引 | 快速合并同結構數據 |
df.join() | 基于索引的快速合并(默認左連接) | 按索引合并多個 DataFrame |
內連接規則:僅保留?'key'
?列在兩表中都存在的值(K0
?和?K2
),以 left 的 key 為主,找共同有的元素
4.笛卡爾連接
關鍵點:on=‘key’
5.左連接合并
6.根據索引合并
為什么C和D的值的NaN?因為 right?的標簽的 abc,不是012
7.合并重疊數據
基本語法
df1.combine_first(df2) # 用 df2 的值填充 df1 的缺失值
注意:right的標簽順序
七、數據重塑
方法 | 轉換方向 | 作用 |
---|---|---|
stack() | 列 → 行(寬 → 長) | 將列標簽轉為行索引(多級索引) |
unstack() | 行 → 列(長 → 寬) | 將行索引轉為列標簽(常用于逆操作) |
melt() | 多列 → 兩列(id_vars + value_vars) | 將指定列保留為標識符,其余列轉為值列 |
1.stack()方法
2.unstack()方法
3.重塑旋轉
future_stack=True
?是 Pandas 2.1.0 版本引入的一個參數,用于啟用?stack()
?方法的新實現邏輯。這個參數的出現是為了平滑過渡到未來版本中默認的?stack()
?行為,避免舊代碼在升級后產生意外結果。
新舊實現的核心差異
場景 | 舊實現( 默認 stack() ) | 新實現 stack(future_stack=True) |
---|---|---|
處理缺失值(NaN) | 可能靜默丟棄或保留?NaN ,取決于索引對齊方式 | 嚴格保留所有索引,未匹配的值用?NaN ?填充 |
多級索引堆疊 | 行為較寬松,可能導致索引層級混亂 | 強制保持索引層級的一致性,避免潛在的歧義 |
重復列名處理 | 允許重復列名,堆疊后可能生成重復的索引 | 強制要求列名唯一(否則拋出?ValueError ) |
性能優化 | 某些情況下可能較慢 | 優化了內存使用和計算效率 |
level=1
?表示對列索引的第二層(“A 教室”“B 教室” 這一層)進行堆疊
關鍵差異總結
參數 | 堆疊層級 | 結果索引層級 | 列維度保留情況 |
---|---|---|---|
level=-1(默認) | 所有列索引層級 | 原行索引 + 所有列層級 | 無(全部轉為行) |
level=1 | 僅第 1 層列索引 | 原行索引 + 第 1 層列索引 | 第 0 層列索引保留為列 |
核心作用
- 列轉行:將 DataFrame 中指定層級的列索引(若有多級列索引)移動到行索引,形成多級行索引。
- 結構轉換:例如,原數據中某幾列代表不同分類的指標,堆疊后這些分類指標轉為行的一部分,數據整體更 “長” 更 “窄”。
4.軸向旋轉
pivot()
?是數據處理中用于重塑數據結構的函數,常見于 Pandas 庫,作用類似 “透視表”,能將數據從長格式轉換為寬格式,便于分析。
Pandas 中?pivot()
?的語法與參數
- 語法:
pivot(index=None, columns=None, values=None) → DataFrame
- 參數說明:
index
:指定一列作為新 DataFrame 的行索引。columns
:指定一列的值作為新 DataFrame 的列名(必須傳值)。values
:指定一列作為新 DataFrame 的值(可選,若省略,原 DataFrame 的列會保留在結果中)。
形成一個直觀的手機降價對比圖
八、數據轉換
1.面元劃分
pd.cut()
?是 Pandas 庫中用于將連續型數值數據切分為離散區間(分箱)的函數,常用于數據預處理、分組分析或可視化。通過設定區間規則,它能將連續值轉換為分類數據(如將年齡分為 “青年”“中年”“老年”),便于進一步分析。
pd.cut()
?是 Pandas 中用于將連續型數據劃分為離散區間(分箱)的函數,其參數說明如下:
x
- 輸入的一維數據(如?
Series
、數組或列表),是待分箱的數據源,必須為一維結構。
bins
- 定義分箱的依據,有三種形式:
- 若為?整數,表示將數據等寬劃分為指定數量的區間(如?
bins=3
?表示分成 3 個等寬區間)。- 若為?序列(如?
[10, 20, 30]
),按指定邊界劃分區間(區間默認為左開右閉,如?(10,20]
)。- 若為?間隔索引(
IntervalIndex
),需確保區間不重疊。
right
- 布爾值,默認為?
True
,表示區間是否包含右邊界。
- 例:
bins=[1,2,3]
?且?right=True
?時,區間為?(1,2]
、(2,3]
;若?right=False
,則為?[1,2)
、[2,3)
。
labels
- 為分箱指定標簽,需與分箱數量一致。
- 若為?數組,標簽直接對應每個區間(如?
labels=['低','中','高']
)。- 若為?
False
,則返回數據所在區間的整數指示(如?0,1,2
?表示第 1、2、3 個區間)。
retbins
- 布爾值,默認為?
False
。若設為?True
,除返回分箱結果外,還會返回區間邊界。
precision
- 整數,默認?
3
,用于指定區間邊界的小數精度(如?precision=2
?表示保留兩位小數)。
include_lowest
- 布爾值,默認為?
False
,表示區間左邊界是否閉合。
- 例:
bins=[10,20]
?且?include_lowest=True
?時,左區間為?[10,20]
(否則為?(10,20]
)。
duplicates
- 處理分箱臨界值重復的方式,可選?
'raise'
(默認,重復時報錯)或?'drop'
(忽略重復邊界)。
2.啞變量處理
啞變量處理(Dummy Variable Treatment)是將分類變量(如性別、職業、商品類別等非數值型變量)轉換為若干個二元變量(取值為 0 或 1)的過程。其核心目的是將定性的分類信息轉化為數值形式,使機器學習、統計分析等模型能夠有效處理這些數據。例如,性別變量有 “男”“女” 兩類,可生成一個啞變量(1 代表男,0 代表女);若分類變量有n個類別,通常生成\(n-1\)個啞變量(以其中一個類別作為參照),避免多重共線性。
pd.get_dummies()
?是 Pandas 中用于將分類變量轉換為啞變量(虛擬變量)的函數,其常見參數如下:
data
- 必選參數,輸入需要進行啞變量轉換的數據,支持?
Series
、DataFrame
?或類似數組(array-like
)的結構。
prefix
- 可選參數,用于定義啞變量列名的前綴。可以是字符串、字符串列表或字典(鍵為列名,值為對應前綴)。例如,設置?
prefix='cat'
,生成的啞變量列名可能為?cat_類別1
、cat_類別2
。
prefix_sep
- 可選參數,默認為?
'_'
,用于連接前綴和原始列名(當前綴存在時)。如?prefix='cat'
?且?prefix_sep='/'
,列名可能為?cat/類別1
。
dummy_na
- 可選參數,布爾值,默認為?
False
。若設為?True
,會為缺失值(NaN
)單獨生成一列(值為?1
?表示該樣本為缺失值,否則為?0
)。
columns
- 可選參數,指定需要進行啞變量編碼的列。若為?
None
(默認),則對所有?object
、string
?或?category
?數據類型的列進行轉換。
sparse
- 可選參數,布爾值,默認為?
False
。若設為?True
,返回的啞變量數據將以稀疏矩陣形式存儲,用于節省內存(適用于大量零值的場景)。
drop_first
- 可選參數,布爾值,默認為?
False
。若設為?True
,會刪除每個分類變量的第一個類別對應的啞變量列,以避免多重共線性(常用于回歸分析等場景)。
dtype
- 可選參數,指定生成的啞變量列的數據類型(如?
np.uint8
、bool
?等),默認為?np.uint8
。
以下操作基于上面練習的實操,所需的兩個資源已經放在資源包里了
?九、預處理二手房數據(綜合案例)
1.查看數據1
2.查看數據2
3.數據統一
因為數據表的數據不一致