現在位置: 首頁 > Pandas 教程 > 正文

Pandas 數據清洗

數據清洗是對一些沒有用的數據進行處理的過程。

很多數據集存在數據缺失、數據格式錯誤、錯誤數據或重復數據的情況,如果要對使數據分析更加準確,就需要對這些沒有用的數據進行處理。

在這個教程中,我們將利用 Pandas包來進行數據清洗。

本文使用到的測試數據 property-data.csv 如下:

上表包含來四種空數據:

  • n/a
  • NA
  • na

Pandas 清洗空值

如果我們要刪除包含空字段的行,可以使用 dropna() 方法,語法格式如下:

DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)

參數說明:

  • axis:默認為 0,表示逢空值剔除整行,如果設置參數 axis=1 表示逢空值去掉整列。
  • how:默認為 'any' 如果一行(或一列)里任何一個數據有出現 NA 就去掉整行,如果設置 how='all' 一行(或列)都是 NA 才去掉這整行。
  • thresh:設置需要多少非空值的數據才可以保留下來的。
  • subset:設置想要檢查的列。如果是多個列,可以使用列名的 list 作為參數。
  • inplace:如果設置 True,將計算得到的值直接覆蓋之前的值并返回 None,修改的是源數據。

我們可以通過 isnull() 判斷各個單元格是否為空。

實例

import pandas as pd

df = pd.read_csv('property-data.csv')

print (df['NUM_BEDROOMS'])
print (df['NUM_BEDROOMS'].isnull())

以上實例輸出結果如下:

以上例子中我們看到 Pandas 把 n/a 和 NA 當作空數據,na 不是空數據,不符合我們要求,我們可以指定空數據類型:

實例

import pandas as pd

missing_values = ["n/a", "na", "--"]
df = pd.read_csv('property-data.csv', na_values = missing_values)

print (df['NUM_BEDROOMS'])
print (df['NUM_BEDROOMS'].isnull())

以上實例輸出結果如下:

接下來的實例演示了刪除包含空數據的行。

實例

import pandas as pd

df = pd.read_csv('property-data.csv')

new_df = df.dropna()

print(new_df.to_string())

以上實例輸出結果如下:

注意:默認情況下,dropna() 方法返回一個新的 DataFrame,不會修改源數據。

如果你要修改源數據 DataFrame, 可以使用 inplace = True 參數:

實例

import pandas as pd

df = pd.read_csv('property-data.csv')

df.dropna(inplace = True)

print(df.to_string())

以上實例輸出結果如下:

我們也可以移除指定列有空值的行:

實例

移除 ST_NUM 列中字段值為空的行:

import pandas as pd

df = pd.read_csv('property-data.csv')

df.dropna(subset=['ST_NUM'], inplace = True)

print(df.to_string())

以上實例輸出結果如下:

我們也可以 fillna() 方法來替換一些空字段:

實例

使用 12345 替換空字段:

import pandas as pd

df = pd.read_csv('property-data.csv')

df.fillna(12345, inplace = True)

print(df.to_string())

以上實例輸出結果如下:

我們也可以指定某一個列來替換數據:

實例

使用 12345 替換 PID 為空數據:

import pandas as pd

df = pd.read_csv('property-data.csv')

df['PID'].fillna(12345, inplace = True)

print(df.to_string())

以上實例輸出結果如下:

替換空單元格的常用方法是計算列的均值、中位數值或眾數。

Pandas使用 mean()、median()mode() 方法計算列的均值(所有值加起來的平均值)、中位數值(排序后排在中間的數)和眾數(出現頻率最高的數)。

實例

使用 mean() 方法計算列的均值并替換空單元格:

import pandas as pd

df = pd.read_csv('property-data.csv')

x = df["ST_NUM"].mean()

df["ST_NUM"].fillna(x, inplace = True)

print(df.to_string())

以上實例輸出結果如下,紅框為計算的均值替換來空單元格:

實例

使用 median() 方法計算列的中位數并替換空單元格:

import pandas as pd

df = pd.read_csv('property-data.csv')

x = df["ST_NUM"].median()

df["ST_NUM"].fillna(x, inplace = True)

print(df.to_string())

以上實例輸出結果如下,紅框為計算的中位數替換來空單元格:

實例

使用 mode() 方法計算列的眾數并替換空單元格:

import pandas as pd

df = pd.read_csv('property-data.csv')

x = df["ST_NUM"].mode()

df["ST_NUM"].fillna(x, inplace = True)

print(df.to_string())

以上實例輸出結果如下,紅框為計算的眾數替換來空單元格:


Pandas 清洗格式錯誤數據

數據格式錯誤的單元格會使數據分析變得困難,甚至不可能。

我們可以通過包含空單元格的行,或者將列中的所有單元格轉換為相同格式的數據。

以下實例會格式化日期:

實例

import pandas as pd

# 第三個日期格式錯誤
data = {
  "Date": ['2020/12/01', '2020/12/02' , '20201226'],
  "duration": [50, 40, 45]
}

df = pd.DataFrame(data, index = ["day1", "day2", "day3"])

df['Date'] = pd.to_datetime(df['Date'])

print(df.to_string())

以上實例輸出結果如下:

           Date  duration
day1 2020-12-01        50
day2 2020-12-02        40
day3 2020-12-26        45

Pandas 清洗錯誤數據

數據錯誤也是很常見的情況,我們可以對錯誤的數據進行替換或移除。

以下實例會替換錯誤年齡的數據:

實例

import pandas as pd

person = {
  "name": ['Google', 'Runoob' , 'Taobao'],
  "age": [50, 40, 12345]    # 12345 年齡數據是錯誤的
}

df = pd.DataFrame(person)

df.loc[2, 'age'] = 30 # 修改數據

print(df.to_string())

以上實例輸出結果如下:

     name  age
0  Google   50
1  Runoob   40
2  Taobao   30

也可以設置條件語句:

實例

將 age 大于 120 的設置為 120:

import pandas as pd

person = {
  "name": ['Google', 'Runoob' , 'Taobao'],
  "age": [50, 200, 12345]    
}

df = pd.DataFrame(person)

for x in df.index:
  if df.loc[x, "age"] > 120:
    df.loc[x, "age"] = 120

print(df.to_string())

以上實例輸出結果如下:

     name  age
0  Google   50
1  Runoob  120
2  Taobao  120

也可以將錯誤數據的行刪除:

實例

將 age 大于 120 的刪除:

import pandas as pd

person = {
  "name": ['Google', 'Runoob' , 'Taobao'],
  "age": [50, 40, 12345]    # 12345 年齡數據是錯誤的
}

df = pd.DataFrame(person)

for x in df.index:
  if df.loc[x, "age"] > 120:
    df.drop(x, inplace = True)

print(df.to_string())

以上實例輸出結果如下:

     name  age
0  Google   50
1  Runoob   40

Pandas 清洗重復數據

如果我們要清洗重復數據,可以使用 duplicated()drop_duplicates() 方法。

如果對應的數據是重復的,duplicated() 會返回 True,否則返回 False。

實例

import pandas as pd

person = {
  "name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
  "age": [50, 40, 40, 23]  
}
df = pd.DataFrame(person)

print(df.duplicated())

以上實例輸出結果如下:

0    False
1    False
2     True
3    False
dtype: bool

刪除重復數據,可以直接使用drop_duplicates() 方法。

實例

import pandas as pd

persons = {
  "name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
  "age": [50, 40, 40, 23]  
}

df = pd.DataFrame(persons)

df.drop_duplicates(inplace = True)
print(df)

以上實例輸出結果如下:

     name  age
0  Google   50
1  Runoob   40
3  Taobao   23
火灭小说网