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 出現次數和缺失值]

這個流程圖描述了從載入資料到計算和顯示 DURATIONend_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_atDURATIONend_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 會被更新,包含兩個新的欄位:datetime。這些欄位分別包含了日期和時間的資料。

   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 的應用技巧,並關注其與其他資料科學工具的整合,將是未來資料分析領域的重要方向。