在進行回歸建模之前,我們通常需要清洗數據。
下面是數據清洗的定義
數據清洗:從記錄集、表或資料庫中檢測和修正(或刪除)受損或不準確記錄的過程。它識別出數據中不完善、不準確或不相關的部分,並替換、修改或刪除這些髒亂的數據。
本文還是以合併完成後的CEIC數據作為例子,進行講解。
import pandas as pd
import seaborn as sns
import numpy as np
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all" #這兩行代碼用來使執行單元輸出所有運行結果。df = pd.read_excel(r"D:\Pythonwork\CEIC\CEIC待處理數據.xlsx")
df.head()
df = df[df.year.between(2003,2018)]統計年鑑從2003年開始記錄SO2排放量數據,含有SO2排放量的數據,一般是從2003年開始的。所以選擇year在2003年以後的。
對一列數據來說,如果某個城市在時間上的數據缺失超過70%,那麼他就沒有被插值的必要。
df = df.set_index(["year","provs","citys"])
time_span = df.index.to_frame()["year"].unique().max() - df.index.to_frame()["year"].unique().min() +1
# 2003-2018年,一共16年數據
time_span
city_nulltime_less70_col = ((df.isnull().groupby("citys").sum() / time_span * 100) < 70) .sum(axis=0)
# 判斷空缺值,並按照城市分組相加;判斷一城市空缺數據<70%,然後每一列加起來的個數。注意這是好的條件
city_nulltime_less70_col
drop_columns = city_nulltime_less70_col[city_nulltime_less70_col < 260].index
#如果一列數據,滿足上述條件的城市個數低於260,則刪除
drop_columns
df.drop(columns=drop_columns,inplace=True)df.tail(20)上面只是根據不滿足條件的城市個數來去掉變量,但是剩下的變量依然有不滿足條件的城市。如下圖所示。所以刪除這些城市
city_nulltime_less70_row = ((df.isnull().groupby("citys").sum() / time_span * 100) < 70).sum(axis = 1)
# 判斷空缺值,並按照城市分組相加;判斷一城市空缺數據<70%,然後每一城市加起來的個數。注意這是好的條件
city_nulltime_less70_row
drop_city = city_nulltime_less70_row[city_nulltime_less70_row<50].index
# 有50列以下的數據是好的 所對應的城市,也就是,只要有4列以上的數據是不好的 所對應的城市。
drop_city
df = df.reset_index().set_index("citys").drop(index=drop_city).reset_index()df_fillna = df.groupby(by = "citys",as_index=False).apply(lambda df: df.interpolate(method = "linear")) #只朝後插值,不朝前
df_fillna = df_fillna.groupby(by = "citys",as_index=False).apply(lambda df: df.interpolate(method = "bfill")) # 朝前原來的推文只進行了第一步,而沒有進行前向插值,這裡改正。
這裡插值的方法,假設條件是,單個個體的某一變量,在時間上是連續的,即受該變量的其他時間的影響,沒有結構突變之類的;並且這一變量不受該個體其他變量的影響。這一假設挺符合直覺的,所以這一方法沒有什麼問題。
現在剩下的有空值的城市,其所有時間都是空值。具體原因不再闡述。所以刪除空值
df_fillna_last = df_fillna.dropna(axis=0,how = "any")下面定位這些城市,進行驗證,發現其所有時間確實都是空值。
df_fillna2 = df_fillna.set_index(["citys","year","provs"])
null = df_fillna2.isnull().sum(axis = 1)
null
null_city = null[null>0].reset_index().citys.unique()
null_city
df_fillna[df_fillna["citys"].isin(null_city)].head(40)df_fillna3 = df_fillna.set_index("citys")
df_fillna3.drop(index= null_city,inplace=True)