NumPy 的 dtype 不僅能定義基本資料型態,還能建構更複雜的結構,例如包含多維陣列的複合型態。這對於處理包含不同資料型態的資料非常有用,例如影像資料或感測器讀數。Pandas 建立在 NumPy 之上,提供更進階的資料結構,例如 Series 和 DataFrame。Series 是一維帶索引的陣列,DataFrame 則是二維的,類別似表格結構,可以方便地處理和分析表格型資料。理解這些資料結構的特性和操作方法,對於資料科學和機器學習至關重要。Pandas 也提供許多便捷的資料操作功能,例如資料篩選、排序、分組和聚合,能大幅提升資料處理效率。此外,Pandas 與其他 Python 資料科學工具鏈的整合性良好,使其成為資料科學領域不可或缺的工具。

進階複合資料型態

NumPy 提供了強大的資料型態定義功能,除了基本的整數、浮點數和字串型態外,我們還可以定義更為複雜的複合型態。以下是幾個例子:

浮點數型態

  • np.dtype('f8'):代表 64 位元浮點數,相當於 np.float64

複數浮點數型態

  • np.dtype('c16'):代表 128 位元複數浮點數,相當於 np.complex256

字串型態

  • np.dtype('S5'):代表長度為 5 的位元組字串。
  • np.dtype('U'):代表 Unicode 字串,相當於 np.str_

Raw Data (void) 型態

  • np.dtype('V'):代表 raw data (void) 型態,相當於 np.void

進階複合型態

我們可以定義更為複雜的複合型態,例如,每個元素包含一個陣列或矩陣的值。以下是定義一個資料型態,其中包含一個 mat 元素,它是一個 3x3 的浮點數矩陣:

import numpy as np

# 定義一個資料型態,其中包含一個 'id' 元素和一個 'mat' 元素
tp = np.dtype([('id', 'i8'), ('mat', 'f8', (3, 3))])

# 建立一個具有此資料型態的 NumPy 陣列
X = np.zeros(1, dtype=tp)

在這個例子中,tp 是一個複合資料型態,它包含兩個元素:idmatid 是一個 64 位元整數,而 mat 是一個 3x3 的浮點數矩陣。然後,我們建立了一個具有此資料型態的 NumPy 陣列 X

內容解密:

  • np.dtype() 函式用於定義 NumPy 資料型態。
  • ('id', 'i8') 定義了一個名為 id 的元素,其資料型態為 64 位元整數。
  • ('mat', 'f8', (3, 3)) 定義了一個名為 mat 的元素,其資料型態為 3x3 的浮點數矩陣。
  • np.zeros(1, dtype=tp) 建立了一個具有 tp 資料型態的 NumPy 陣列,大小為 1。

圖表翻譯:

在這個圖表中,我們展示了 NumPy 資料型態的階層結構。基本型態包括整數、浮點數和字串,而複合型態包括陣列和矩陣。在這個例子中,我們定義了一個資料型態,其中包含一個 3x3 的浮點數矩陣和一個 64 位元整數。

結構化陣列的優勢

在 NumPy 中,結構化陣列(structured arrays)是一種強大的資料結構,可以讓您以結構化的方式儲存和存取資料。每個元素在結構化陣列中可以包含多個欄位,例如整數、浮點數或甚至是其他陣列。

例如,假設我們有一個結構化陣列 X,其中每個元素包含一個 ID 和一個 3x3 的矩陣:

print(X[0])
print(X['mat'][0])

輸出結果:

(0, [[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

為什麼要使用結構化陣列而不是簡單的多維陣列或 Python 字典呢?一方面,NumPy 的結構化資料型別可以直接對映到 C 結構定義,因此可以直接在 C 程式中存取陣列內容。如果您需要撰寫 Python 介面來存取 legacy C 或 Fortran 函式庫中的結構化資料,結構化陣列可以提供一個強大的介面。

紀錄陣列:結構化陣列的變體

NumPy 也提供了紀錄陣列(record arrays),它們與結構化陣列非常相似,但有一個額外的功能:欄位可以被存取為屬性而不是字典鍵。回憶一下,我們之前如何存取樣本資料集中的年齡:

data['age']

如果我們將資料視為紀錄陣列,我們可以使用以下語法存取年齡:

data_rec = data.view(np.recarray)
data_rec.age

雖然紀錄陣列有一些額外的 overhead,但它們提供了一種更方便的存取欄位的方式。

效能比較

讓我們比較一下存取欄位的效能:

%timeit data['age']
%timeit data_rec['age']
%timeit data_rec.age

結果顯示,存取欄位的效能差異不大,但使用紀錄陣列的屬性存取方式略慢一些。

圖表翻譯:

內容解密:

在這個例子中,我們探討了 NumPy 中的結構化陣列和紀錄陣列。結構化陣列可以讓您以結構化的方式儲存和存取資料,而紀錄陣列提供了一種更方便的存取欄位的方式。雖然紀錄陣列有一些額外的 overhead,但它們提供了一種更直觀的存取欄位的方式。

使用Pandas進行資料操作

Pandas是一個根據NumPy的套件,提供了一種高效的資料結構和操作方法,稱為DataFrame。DataFrame是一種多維陣列,附帶有行和列標籤,通常具有異質的資料型別和/或缺失資料。除了提供了一個方便的儲存介面外,Pandas還實作了許多強大的資料操作,包括資料函式庫框架和試算表程式的功能。

Pandas的優點

Pandas的優點在於它能夠提供一個高效的資料操作方法,尤其是在處理具有標籤的資料和缺失資料時。它還提供了一個方便的儲存介面和強大的資料操作功能,包括分組、樞紐分析等。

安裝Pandas

要安裝Pandas,需要先安裝NumPy。如果您使用Anaconda堆積疊,則已經安裝了Pandas。否則,您可以參考Pandas檔案中的安裝過程。

匯入Pandas

一旦安裝了Pandas,您就可以匯入它並檢查版本:

import pandas as pd
print(pd.__version__)

使用Pandas

在本文的其餘部分,我們將關注於如何有效地使用Series、DataFrame和相關結構。我們將使用真實的資料集作為例子,但這些例子不是我們的主要焦點。

內建檔案

在您閱讀本文的同時,不要忘記IPython提供了快速瀏覽套件內容和函式檔案的能力。您可以使用?字元來顯示函式的檔案:

import pandas as pd
pd?

顯示Pandas名稱空間

您可以使用以下命令來顯示Pandas名稱空間的所有內容:

import pandas as pd
dir(pd)
程式碼示例
import pandas as pd

# 建立一個簡單的DataFrame
data = {'Name': ['John', 'Anna', 'Peter', 'Linda'],
        'Age': [28, 24, 35, 32],
        'Country': ['USA', 'UK', 'Australia', 'Germany']}
df = pd.DataFrame(data)

# 顯示DataFrame
print(df)

圖表翻譯

圖表說明

上述圖表顯示了使用Pandas進行資料操作的流程。首先,我們匯入資料到Pandas中,然後對資料進行操作,最後將操作結果儲存到檔案中。

瞭解Pandas:基礎物件與資料結構

Pandas是一個強大的Python資料分析函式庫,它提供了多種資料結構和工具來幫助您高效地處理和分析資料。在本章中,我們將探討Pandas的基礎物件,包括Series、DataFrame和Index。

Series:一維陣列的索引資料

Pandas Series是一個一維陣列的索引資料結構。它可以從一個列表或陣列中建立,例如:

import pandas as pd

data = pd.Series([0.25, 0.5, 0.75, 1.0])
print(data)

輸出結果:

0    0.25
1    0.50
2    0.75
3    1.00
dtype: float64

如您所見,Series結合了一個值序列和一個索引序列。您可以使用valuesindex屬性來存取這些序列。

內容解密:

import pandas as pd

# 建立一個Series物件
data = pd.Series([0.25, 0.5, 0.75, 1.0])

# 存取值序列
print(data.values)

# 存取索引序列
print(data.index)

這段程式碼展示瞭如何建立一個Series物件,並存取其值序列和索引序列。

DataFrame:二維陣列的索引資料

Pandas DataFrame是一個二維陣列的索引資料結構。它可以從一個字典或列表中建立,例如:

import pandas as pd

data = {'Name': ['John', 'Mary', 'David'], 
        'Age': [25, 31, 42]}
df = pd.DataFrame(data)
print(df)

輸出結果:

     Name  Age
0    John   25
1    Mary   31
2   David   42

如您所見,DataFrame結合了一個值陣列和一個索引陣列。您可以使用columnsindex屬性來存取這些陣列。

內容解密:

import pandas as pd

# 建立一個DataFrame物件
data = {'Name': ['John', 'Mary', 'David'], 
        'Age': [25, 31, 42]}
df = pd.DataFrame(data)

# 存取欄位名稱
print(df.columns)

# 存取索引序列
print(df.index)

這段程式碼展示瞭如何建立一個DataFrame物件,並存取其欄位名稱和索引序列。

Index:索引序列

Pandas Index是一個索引序列,它可以用來存取Series或DataFrame中的資料。例如:

import pandas as pd

data = pd.Series([0.25, 0.5, 0.75, 1.0])
print(data.index)

輸出結果:

RangeIndex(start=0, stop=4, step=1)

如您所見,Index是一個RangeIndex物件,它代表了一個連續的整數序列。

圖表翻譯:

這個圖表展示了Series、Index和Values之間的關係。Index是一個索引序列,它可以用來存取Series中的資料。Values是一個NumPy陣列,它代表了Series中的值。

使用Pandas Series進行資料操作

Pandas Series是一種一維資料結構,類別似於NumPy陣列,但具有更多的功能和彈性。下面是使用Pandas Series進行資料操作的範例。

建立Pandas Series

import pandas as pd

# 建立一個Pandas Series
data = pd.Series([0.25, 0.5, 0.75, 1.0])
print(data)

輸出:

0    0.25
1    0.50
2    0.75
3    1.00
dtype: float64

存取資料

Pandas Series可以使用索引存取資料。索引可以是整數或字串。

# 使用整數索引存取資料
print(data[1])  # 輸出:0.5

# 使用切片存取資料
print(data[1:3])  # 輸出:
# 1    0.50
# 2    0.75
# dtype: float64

自定義索引

Pandas Series可以使用自定義索引。索引可以是任何型別的值,例如字串。

# 建立一個Pandas Series具有自定義索引
data = pd.Series([0.25, 0.5, 0.75, 1.0], index=['a', 'b', 'c', 'd'])
print(data)

輸出:

a    0.25
b    0.50
c    0.75
d    1.00
dtype: float64

圖表表示

可以使用Plantuml圖表來表示Pandas Series的資料結構。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title NumPy Pandas 資料結構操作與應用

package "Pandas 資料處理" {
    package "資料結構" {
        component [Series
一維陣列] as series
        component [DataFrame
二維表格] as df
        component [Index
索引] as index
    }

    package "資料操作" {
        component [選取 Selection] as select
        component [篩選 Filtering] as filter
        component [分組 GroupBy] as group
        component [合併 Merge/Join] as merge
    }

    package "資料轉換" {
        component [重塑 Reshape] as reshape
        component [透視表 Pivot] as pivot
        component [聚合 Aggregation] as agg
    }
}

series --> df : 組成
index --> df : 索引
df --> select : loc/iloc
df --> filter : 布林索引
df --> group : 分組運算
group --> agg : 聚合函數
df --> merge : 合併資料
df --> reshape : melt/stack
reshape --> pivot : 重新組織

note right of df
  核心資料結構
  類似 Excel 表格
end note

@enduml

圖表翻譯:

上述Plantuml圖表表示Pandas Series的資料結構。Series是最上層的結構,下面是索引和值。索引可以是整數或字串,值可以是任何型別的資料。資料型別表示Series中儲存的資料型別。

內容解密:

Pandas Series是一種強大的資料結構,可以用於儲存和操作一維資料。它具有更多的功能和彈性,例如自定義索引和資料型別。透過使用Pandas Series,可以簡單地存取和運算元據,並且可以使用Plantuml圖表來表示其資料結構。

從資料結構設計的視角來看,NumPy 和 Pandas 提供的進階複合資料型態和資料結構,展現了 Python 在資料科學領域的強大能力。透過定義包含陣列或矩陣的複合型態,NumPy 能夠有效處理複雜的科學運算資料。Pandas 的 DataFrame 和 Series 則更進一步,藉由引入索引和標籤,簡化了資料的存取和操作,尤其在處理異質資料和缺失值方面更具優勢。

分析 NumPy 和 Pandas 的效能表現,可以發現結構化陣列和紀錄陣列的存取速度差異不大,但紀錄陣列的屬性存取略微遜色。這意味著在追求極致效能的場景下,需要仔細權衡資料結構的選擇。此外,Pandas 建立在 NumPy 基礎之上,提供了更高階的資料操作功能,例如分組、樞紐分析等,更能滿足資料分析的實際需求。然而,Pandas 的額外功能也帶來了些許效能開銷,在處理大規模資料時需留意資源消耗。

展望未來,隨著資料科學領域的持續發展,預計 NumPy 和 Pandas 將持續演進,以支援更複雜的資料型態和更強大的資料操作功能。例如,支援 GPU 加速運算、整合更多機器學習演算法等。同時,社群也將持續發展更豐富的工具和資源,進一步降低使用門檻,讓更多開發者能輕鬆駕馭這些強大的工具。

玄貓認為,對於資料科學領域的開發者而言,深入理解 NumPy 和 Pandas 的底層機制和效能特點至關重要。唯有如此,才能根據實際需求選擇合適的資料結構和操作方法,最大程度地發揮其效能優勢,並在處理大規模資料時避免效能瓶頸。