Pandas 是 Python 中常用的資料處理函式函式庫,提供高效的資料結構和資料分析工具。在實際應用中,原始資料往往存在缺失值、格式不一致等問題,需要進行前處理和清理才能用於分析。本文將介紹一些 Pandas 常用的資料前處理技巧,包含處理缺失值、日期時間格式轉換、欄位重塑、條件指定等,幫助讀者提升資料分析效率。這些技巧涵蓋了資料清理、轉換和增強的各個方面,從而使資料更適合分析和建模。
時間分佈分析
首先,我們來看一下 DURATION
欄位的分佈情況。使用 value_counts()
方法,並設定 normalize=True
以取得相對頻率:
df['DURATION'].value_counts(normalize=True)
結果顯示,沒有單一值佔據了相對較高的比例:
- 0:04:00 佔 2.5847%
- 0:03:00 佔 2.5284%
- 0:05:00 佔 2.2808%
- 0:06:00 佔 2.0333%
- 0:07:00 佔 1.9644%
這意味著資料中有多種不同的時間長度,並且沒有明顯的主導值。
處理缺失值
接下來,我們來探討 end_location_name
欄位的狀況。使用 value_counts()
方法,並設定 dropna=False
以顯示缺失值的數量:
df['end_location_name'].value_counts(dropna=False)
結果顯示,end_location_name
欄位中有 2070 個缺失值(NaN),佔比相當高。此外,其他值的出現次數也被列出:
- NaN: 2070
- 1898 Mountain Rd NW, Albuquerque, NM 87104, USA: 802
- Central @ Tingley, Albuquerque, NM 87104, USA: 622
- 330 Tijeras Ave NW, Albuquerque, NM 87102, USA: 529
- 2550 Central Ave NE, Albuquerque, NM 87106, USA: 478
這些資訊對於後續的資料清理和分析工作非常重要。
內容解密:
上述程式碼使用 Pandas 的 value_counts()
方法來計算每個唯一值在資料中的出現次數。設定 normalize=True
可以取得相對頻率,設定 dropna=False
可以顯示缺失值的數量。這些方法可以幫助我們快速瞭解資料的分佈和特性。
圖表翻譯:
以下是使用 Mermaid 流程圖描述上述分析過程:
flowchart TD A[載入資料] --> B[計算 DURATION 分佈] B --> C[顯示 DURATION 相對頻率] A --> D[計算 end_location_name 分佈] D --> E[顯示 end_location_name 出現次數和缺失值]
這個流程圖描述了從載入資料到計算和顯示 DURATION
和 end_location_name
欄位的分佈的過程。
處理缺失值的方法
在進行資料分析時,瞭解資料中的缺失值是非常重要的。缺失值可能會對分析結果產生影響,因此需要進行適當的處理。
檢查缺失值
首先,我們需要檢查資料中有多少個缺失值。可以使用 isnull()
方法來檢查缺失值,並結合 sum()
方法來取得缺失值的數量。
import pandas as pd
# 建立一個範例資料框
data = {
'month': [1, 2, 3],
'trip_id': [101, 102, 103],
'region_id': [1, 2, 3],
'vehicle_id': [1001, 1002, 1003],
'started_at': ['2022-01-01', '2022-01-02', '2022-01-03'],
'ended_at': ['2022-01-01', '2022-01-02', None],
'DURATION': [10, 20, None],
'start_location_name': ['A', 'B', 'C'],
'end_location_name': ['D', None, 'F']
}
df = pd.DataFrame(data)
# 檢查缺失值
missing_values = df.isnull().sum()
print(missing_values)
處理缺失值
在上面的範例中,我們可以看到 ended_at
、DURATION
和 end_location_name
欄位中有缺失值。接下來,我們需要決定如何處理這些缺失值。
刪除缺失值
一種方法是直接刪除含有缺失值的列或列中的資料。
# 刪除含有缺失值的列
df.dropna(axis=1, how='any', inplace=True)
# 刪除含有缺失值的列中的資料
df.dropna(axis=0, how='any', inplace=True)
填充缺失值
另一種方法是填充缺失值,可以使用 fillna()
方法。
# 填充缺失值為 0
df.fillna(0, inplace=True)
# 填充缺失值為平均值
df['DURATION'].fillna(df['DURATION'].mean(), inplace=True)
使用插補法
也可以使用插補法來填充缺失值,例如使用 interpolate()
方法。
# 使用插補法填充缺失值
df['DURATION'].interpolate(method='linear', limit_direction='both', inplace=True)
資料清理、轉換和增強
在探索和分析資料的過程中,我們已經對資料有了一定的瞭解,包括了什麼是資料、資料中存在什麼問題,例如空值、不適當的資料型別、合併欄位等。現在,讓我們開始學習如何解決這些常見的資料問題。
使用 value_counts()
方法
value_counts()
方法是一種用於計算每個唯一值出現次數的方法。除了計算唯一值的次數外,它還可以根據指定的二元組(bins)對數值進行分組。
import pandas as pd
# 建立一個範例 DataFrame
data = {
'trip_id': [1787135, 1700235, 1874035, 1960935, 2047835,
2221635, 2308535, 2134735, 2395435, 2482335,
1612465]
}
df = pd.DataFrame(data)
# 使用 value_counts() 方法,指定 bins 引數
print(df['trip_id'].value_counts(bins=10))
這個範例展示瞭如何使用 value_counts()
方法對 trip_id
欄位進行分組,並計算每個分組的出現次數。雖然這個範例的結果可能不是非常有意義,但如果應用於像年齡這樣的欄位時,就可以快速建立年齡組並瞭解其分佈情況。
資料清理和轉換
在瞭解了資料的問題後,下一步就是開始清理和轉換資料。這個過程包括了處理空值、轉換資料型別、合併欄位等。接下來的章節將會詳細介紹如何解決這些常見的資料問題。
資料增強
除了清理和轉換資料外,資料增強也是資料預處理的一個重要步驟。資料增強包括了增加新的欄位、計算衍生變數等,以使得資料更加豐富和有用。這些步驟都將在後續章節中進行詳細介紹。
處理常見資料問題
即使您的資料看起來完美無缺,您的系統也可能存在一些問題。這些問題可能是由於資料採集或資料輸入的原因。讓我們以電動滑板車資料集為例,該資料集是使用GPS收集的,幾乎沒有人工輸入,但仍然存在一些問題,例如有些終點位置缺失。這種情況看起來很奇怪,但它確實存在。
刪除列和行
在修改資料之前,您應該先決定是否需要使用所有欄位。檢視電動滑板車資料,我們發現有一個名為region_id
的欄位。由於我們只使用阿爾伯克基的資料,因此這個欄位對於我們來說沒有用處。
您可以使用drop
方法刪除欄位。這個方法允許您指定是否刪除行或欄位。行是預設值,因此我們需要指定columns
,如下面的程式碼塊所示:
df.drop(columns=['region_id'], inplace=True)
要刪除行,您只需要指定index
而不是columns
。要刪除索引為34225的行,您需要使用以下程式碼:
df.drop(index=[34225], inplace=True)
刪除根據條件的列和行
如果您想要刪除根據條件的列和行,您可以使用dropna
方法。這個方法允許您指定多個引數,包括:
axis
:指定行或欄位的索引或欄位(0或1)。預設值為行。how
:指定是否刪除行或欄位,如果所有值都是空的或如果任何值是空的(all或any)。預設值為any。thresh
:允許您指定一個整數值,表示必須存在多少個空值。subset
:允許您指定一個列表,包含要搜尋的行或欄位。inplace
:允許您修改現有的DataFrame。預設值為False。
處理空值
檢視電動滑板車資料,我們發現有六行沒有開始位置名稱:
df['start_location_name'][(df['start_location_name'].isnull())]
這些空值可能是由於資料採集或資料輸入的原因。為了處理這些空值,我們可以使用dropna
方法刪除包含空值的行或欄位。
內容解密:
在上面的程式碼中,我們使用drop
方法刪除region_id
欄位。然後,我們使用drop
方法刪除索引為34225的行。接下來,我們使用dropna
方法刪除包含空值的行或欄位。
圖表翻譯:
flowchart TD A[刪除列和行] --> B[刪除根據條件的列和行] B --> C[處理空值] C --> D[刪除包含空值的行或欄位]
在這個圖表中,我們展示了刪除列和行、刪除根據條件的列和行、處理空值和刪除包含空值的行或欄位的流程。
處理缺失值和資料清理
在資料分析中,缺失值是常見的問題。Pandas 提供了多種方法來處理缺失值,包括 dropna()
和 fillna()
。
使用 dropna()
刪除缺失值
如果您想要刪除含有缺失值的行或列,可以使用 dropna()
函式。例如,以下程式碼刪除含有缺失值的行:
df.dropna(subset=['start_location_name'], inplace=True)
這個程式碼會刪除 start_location_name
欄位中含有缺失值的行。
使用 fillna()
填充缺失值
如果您想要填充缺失值,可以使用 fillna()
函式。例如,以下程式碼填充 start_location_name
欄位中的缺失值:
df.fillna(value='00:00:00', axis='columns')
這個程式碼會填充 start_location_name
欄位中的缺失值為 '00:00:00'
。
使用物件填充缺失值
如果您想要使用不同的值填充不同的欄位,可以使用物件填充缺失值。例如,以下程式碼建立一個物件,將 start_location_name
欄位中的缺失值填充為 'Street A'
,將 end_location_name
欄位中的缺失值填充為 'Street B'
:
value_obj = {'start_location_name': 'Street A', 'end_location_name': 'Street B'}
df.fillna(value=value_obj)
這個程式碼會填充 start_location_name
欄位中的缺失值為 'Street A'
,填充 end_location_name
欄位中的缺失值為 'Street B'
。
篩選和處理資料
您可以使用篩選條件來選擇要處理的資料。例如,以下程式碼篩選出 start_location_name
欄位中含有缺失值的行:
startstop = df[(df['start_location_name'].isnull()) & (df['end_location_name'].isnull())]
這個程式碼會篩選出 start_location_name
欄位中含有缺失值的行,並將結果儲存到 startstop
變數中。
資料清理與轉換
在資料分析中,資料清理與轉換是一個非常重要的步驟。這個步驟可以幫助我們去除不需要的資料,轉換資料格式,讓資料更加適合分析。
缺失值處理
首先,我們需要處理缺失值。缺失值是指資料中某些欄位的值為空或未知。以下是處理缺失值的範例:
import pandas as pd
# 建立一個 DataFrame
data = {'start_location_name': ['A', 'B', None, 'D'],
'end_location_name': ['E', 'F', None, 'H']}
df = pd.DataFrame(data)
# 尋找缺失值
print(df[df['start_location_name'].isnull()])
# 填充缺失值
value = {'start_location_name': 'Start St.', 'end_location_name': 'Stop St.'}
df.fillna(value=value)
print(df[['start_location_name', 'end_location_name']])
這個範例中,我們使用 isnull()
方法尋找缺失值,然後使用 fillna()
方法填充缺失值。
資料過濾
接下來,我們需要過濾資料。過濾資料可以幫助我們去除不需要的資料。以下是過濾資料的範例:
# 建立一個 DataFrame
data = {'month': ['May', 'June', 'May', 'July'],
'trip_id': [1, 2, 3, 4]}
df = pd.DataFrame(data)
# 過濾資料
may_df = df[df['month'] == 'May']
print(may_df)
這個範例中,我們使用布林值索引過濾資料,選擇 month
欄位為 ‘May’ 的資料。
資料轉換
最後,我們需要轉換資料。轉換資料可以幫助我們將資料轉換成適合分析的格式。以下是轉換資料的範例:
# 建立一個 DataFrame
data = {'month': ['May', 'June', 'May', 'July'],
'trip_id': [1, 2, 3, 4]}
df = pd.DataFrame(data)
# 轉換資料
df['month'] = df['month'].astype('category')
print(df.dtypes)
這個範例中,我們使用 astype()
方法將 month
欄位轉換成型別別。
圖表翻譯:
graph LR A[資料清理] --> B[資料過濾] B --> C[資料轉換] C --> D[資料分析]
這個圖表展示了資料清理、過濾、轉換和分析的流程。
內容解密:
這個範例中,我們使用 Pandas 函式庫來處理資料。Pandas 函式庫提供了很多方法來處理缺失值、過濾資料和轉換資料。這些方法可以幫助我們將資料轉換成適合分析的格式。
資料前處理與清理
在進行資料分析之前,資料的清理和前處理是一個非常重要的步驟。這個過程包括了處理缺失值、資料格式化、以及移除不需要的資料。
移除不需要的資料
首先,我們需要移除不需要的資料。例如,如果我們有一個 DataFrame,包含了多個月份的資料,但我們只需要某些月份的資料,我們可以使用 drop()
方法來移除不需要的資料。
# 移除 May 月份的資料
df.drop(index=may.index, inplace=True)
資料格式化
接下來,我們需要格式化資料。例如,如果我們的資料中有一個欄位的名稱全部都是大寫,我們可以使用以下方法來將其轉換為小寫。
# 將欄位名稱轉換為小寫
df.columns = df.columns.str.lower()
或者,如果我們需要將某些欄位名稱進行特定的修改,我們可以使用 rename()
方法。
# 將 DURATION 欄位名稱轉換為小寫
df.rename(columns={'DURATION': 'duration'}, inplace=True)
處理常見的資料問題
在處理資料的過程中,我們常常會遇到一些常見的問題,例如欄位名稱的大小寫問題、缺失值等。以下是幾個常見的資料問題和解決方法。
- 欄位名稱大小寫問題:可以使用
str.lower()
或str.upper()
方法來轉換欄位名稱的大小寫。 - 缺失值:可以使用
dropna()
方法來移除含有缺失值的資料,或者使用fillna()
方法來填充缺失值。
資料轉換和修改
在某些情況下,我們需要對資料進行轉換和修改。例如,如果我們需要將某些欄位的資料型別從字串轉換為數值型別,我們可以使用 pd.to_numeric()
方法。
# 將某些欄位的資料型別轉換為數值型別
df['欄位名稱'] = pd.to_numeric(df['欄位名稱'])
內容解密:
在這個章節中,我們學習瞭如何進行資料前處理和清理。首先,我們需要移除不需要的資料,然後格式化資料。接下來,我們需要處理常見的資料問題,例如欄位名稱的大小寫問題和缺失值。最後,我們可以對資料進行轉換和修改,以滿足具體的分析和模型建立需求。
圖表翻譯:
flowchart TD A[資料前處理] --> B[移除不需要的資料] B --> C[格式化資料] C --> D[處理常見的資料問題] D --> E[資料轉換和修改] E --> F[分析和模型建立]
這個流程圖展示了資料前處理和清理的步驟,從移除不需要的資料開始,然後進行格式化資料、處理常見的資料問題,最後進行資料轉換和修改,以滿足具體的分析和模型建立需求。
資料前處理:重塑欄位名稱和值
在進行資料分析之前,對資料進行適當的前處理是非常重要的。這包括重塑欄位名稱和值,以確保資料的一致性和可讀性。
欄位名稱重塑
首先,讓我們看看如何重塑欄位名稱。假設我們有一個 DataFrame df
,其中有一個欄位名稱為 region_id
,我們想將其重塑為 region
。我們可以使用 rename
方法來完成這個任務:
df.rename(columns={'region_id': 'region'}, inplace=True)
這個方法會將 region_id
欄位重塑為 region
,並且會修改原始的 DataFrame。
欄位值重塑
接下來,讓我們看看如何重塑欄位值。假設我們有一個欄位名稱為 month
,我們想將其值全部轉換為大寫。我們可以使用 str.upper
方法來完成這個任務:
df['month'] = df['month'].str.upper()
這個方法會將 month
欄位的值全部轉換為大寫。
新增欄位
最後,讓我們看看如何新增一個欄位。假設我們想新增一個欄位名稱為 new_column
,並且將其值設定為某個特定的值。我們可以使用以下格式來新增欄位:
df['new_column'] = value
這個格式會建立一個新的欄位,並且將其值設定為指定的值。
條件新增欄位
如果我們想根據某個條件新增欄位,可以使用迴圈來完成這個任務。例如:
for index, row in df.iterrows():
if row['condition'] == True:
df.loc[index, 'new_column'] = value
這個迴圈會根據條件新增欄位,並且將其值設定為指定的值。
資料框架(DataFrame)中的條件指定
在 Pandas 中,當您需要根據某些條件對 DataFrame 進行指定時,有多種方法可以實作。以下是兩種常見的方法,分別是使用迭代和使用 loc()
方法。
方法一:迭代
您可以使用迭代的方式來遍歷 DataFrame 的每一行,並根據條件進行指定。這種方法雖然可以實作需求,但效率可能不是最優的,尤其是在處理大型 DataFrame 時。
import pandas as pd
# 建立一個示例 DataFrame
data = {
'trip_id': [1613335, 1613639, 1613708, 1613867, 1636714],
'new_column': ['No'] * 5 # 初始化 'new_column' 全為 'No'
}
df = pd.DataFrame(data)
# 迭代 DataFrame 並根據條件進行指定
for i, r in df.iterrows():
if r['trip_id'] == 1613335:
df.at[i, 'new_column'] = 'Yes'
else:
df.at[i, 'new_column'] = 'No'
print(df[['trip_id', 'new_column']].head())
方法二:使用 loc()
使用 loc()
方法可以更高效地實作條件指定。您可以直接指定條件、欄位名稱和指定,從而避免了迭代的需要。
import pandas as pd
# 建立一個示例 DataFrame
data = {
'trip_id': [1613335, 1613639, 1613708, 1613867, 1636714],
'new_column': ['No'] * 5 # 初始化 'new_column' 全為 'No'
}
df = pd.DataFrame(data)
# 使用 loc() 方法根據條件進行指定
df.loc[df['trip_id'] == 1613335, 'new_column'] = '1613335'
print(df[['trip_id', 'new_column']].head())
比較
- 效率:使用
loc()
方法通常比迭代更高效,尤其是在大型 DataFrame 中。 - 可讀性:兩種方法都相對容易理解,但
loc()
方法的語法更為簡潔和直觀。 - 適用場景:當您需要根據複雜的條件進行指定,或者需要處理大型 DataFrame 時,使用
loc()
方法可能是更好的選擇。
圖表翻譯:
flowchart TD A[開始] --> B[建立 DataFrame] B --> C[迭代指定或使用 loc()] C --> D[條件判斷] D --> E[根據條件進行指定] E --> F[輸出結果]
這個流程圖展示了從建立 DataFrame 到根據條件進行指定的過程,涵蓋了迭代和使用 loc()
方法的兩種途徑。
處理常見資料問題使用 pandas
在資料分析中,常會遇到資料格式不正確或缺失的問題。使用 pandas,可以輕易地處理這些問題。以下是一個例子,展示如何使用 pandas 處理日期和時間資料。
日期和時間資料處理
假設我們有一個 DataFrame,包含了一列日期和時間的資料。這些資料是以字串的形式儲存的,且格式為「日期 時間」。我們可以使用 pandas 的 str.split()
方法將這些資料分割成日期和時間兩個獨立的欄位。
import pandas as pd
# 建立一個示例 DataFrame
data = {
'trip_id': [1613335, 1613639, 1613708, 1613867, 1636714],
'started_at': ['5/21/2019 18:33', '5/21/2019 19:07', '5/21/2019 19:13', '5/21/2019 19:29', '5/24/2019 13:38']
}
df = pd.DataFrame(data)
# 將日期和時間資料分割成兩個獨立的欄位
new_df = df['started_at'].str.split(' ', expand=True)
# 將新資料指定給原始 DataFrame
df['date'] = new_df[0]
df['time'] = new_df[1]
print(df)
結果
經過上述處理後,原始 DataFrame 會被更新,包含兩個新的欄位:date
和 time
。這些欄位分別包含了日期和時間的資料。
trip_id started_at date time
0 1613335 5/21/2019 18:33 5/21/2019 18:33
1 1613639 5/21/2019 19:07 5/21/2019 19:07
2 1613708 5/21/2019 19:13 5/21/2019 19:13
3 1613867 5/21/2019 19:29 5/21/2019 19:29
4 1636714 5/24/2019 13:38 5/24/2019 13:38
這樣,就可以輕易地將日期和時間資料分割成兩個獨立的欄位,方便後續的資料分析和處理。
資料清理、轉換和增強
在進行資料分析之前,資料清理和轉換是一個非常重要的步驟。這個步驟可以幫助我們去除不需要的資料、轉換資料型別以及增強資料的品質。
從資料清理、缺失值處理、欄位更名到日期時間分割等多個導向的分析來看,有效運用 Pandas 處理資料的重要性顯而易見。觀察產業鏈上下游的技術選擇,Python 生態圈與資料科學的緊密結合已成為主流趨勢。深入剖析 Pandas 的核心功能可以發現,其提供的 value_counts()
、fillna()
、dropna()
、rename()
等方法,能大幅提升資料處理效率,並有效解決資料不一致、缺失值等常見問題。技術堆疊的各層級協同運作中體現,Pandas 不僅簡化了資料清理流程,也為後續的資料分析和視覺化奠定了堅實基礎。然而,Pandas 的效能瓶頸在處理極大型資料集時仍需關注,特別是迭代操作的效率問題。考量開發成本與長期維護資源,建議技術團隊深入理解 Pandas 的向量化操作,並搭配其他效能最佳化技巧,才能最大限度地發揮其效能優勢。對於重視資料品質的企業,善用 Pandas 進行資料前處理將是提升資料分析效率和準確性的關鍵。玄貓認為,持續精進 Pandas 的應用技巧,並關注其與其他資料科學工具的整合,將是未來資料分析領域的重要方向。