返回文章列表

Pandas 資料型別:整數、浮點數、布林值與字串的深度解析

本文探討 Pandas 中各種資料型別的特性、使用方法和注意事項,包含整數、浮點數、布林值和字串,並詳細說明遺漏值的處理方式與不同型別之間的轉換規則。同時,也提供了一些實務應用案例和錯誤教訓,幫助讀者更好地理解和運用 Pandas 進行資料處理。

資料科學 Python

Pandas 提供了多種資料型別,以提升資料處理效率。相較於 Python 內建型別,Pandas 的資料型別在效能方面有顯著優勢,尤其在處理大量資料時,例如使用 pd.Int64Dtype() 可以有效提升整數運算的效率。理解這些資料型別的特性和使用方法,對於撰寫高效能的資料處理程式碼至關重要。尤其在處理不同型別的遺漏值時,更需注意 Pandas 的轉換規則,例如整數型別遇到遺漏值會自動轉換為浮點數型別。

整數型別

整數型別是最基本的資料型別,與Python中的int型別或資料函式庫中的INTEGER型別相似,僅能表示整數。儘管如此,整數在算術運算、索引、計數及列舉等多種應用中都非常實用。整數型別在效能上經過高度最佳化,從pandas一路到電腦硬體都有顯著的提升。pandas提供的整數型別遠比Python標準函式庫的int型別快速,適當使用整數型別通常是高效能、可擴充套件報告的關鍵。

整數型別的使用方法

任何有效的整數序列都可以作為引數傳遞給pd.Series建構函式。搭配dtype=pd.Int64Dtype()引數,你將得到64位元整數資料型別:

pd.Series(range(3), dtype=pd.Int64Dtype())

這段程式碼會產生以下結果:

0    0
1    1
2    2
dtype: Int64

當儲存和計算資源不成問題時,使用者通常會選擇64位元整數,但也可以選擇較小的資料型別:

pd.Series(range(3), dtype=pd.Int8Dtype())

這段程式碼會產生以下結果:

0    0
1    1
2    2
dtype: Int8

內容解密:

  • pd.Series:此函式用於建立一個pandas Series物件,該物件是一維的有序資料結構。
  • range(3):此函式生成一個從0到2的整數序列。
  • dtype=pd.Int64Dtype():此引數指定Series中的資料型別為64位元整數。
  • dtype=pd.Int8Dtype():此引數指定Series中的資料型別為8位元整數。

關於遺漏值的處理,pandas使用pd.NA作為其指標,與資料函式庫中的NULL相似:

pd.Series([1, pd.NA, 2], dtype=pd.Int64Dtype())

這段程式碼會產生以下結果:

0    1
1   <NA>
2    2
dtype: Int64

為了方便使用者,pd.Series建構函式會將Python中的None值自動轉換為pd.NA:

pd.Series([1, None, 2], dtype=pd.Int64Dtype())

這段程式碼會產生以下結果:

0    1
1   <NA>
2    2
dtype: Int64

內容解密:

  • pd.NA:此為pandas中的遺漏值標記,與資料函式庫中的NULL相似。
  • None:Python中的遺漏值標記,會被自動轉換為pd.NA。

對新手的建議

對於剛開始進行科學計算的使用者來說,瞭解pandas中的整數與Python中的int之間的差異非常重要。與Python的int不同,pandas中的整數有固定的上下限。這些限制由整數的寬度和正負號決定。例如,8位元有符號整數(Int8)的範圍是從-128到127。

整合應用案例

假設你在處理一個大量交易紀錄的資料集,其中包含了交易金額和交易時間。你希望快速計算每筆交易的總金額並將結果儲存在一個新的Series中。你可以使用整數型別來進行這些計算,因為它們在效能上經過高度最佳化。

# 假設 transaction_amounts 是一個包含所有交易金額的 Series
transaction_amounts = pd.Series([100, 200, 300], dtype=pd.Int64Dtype())

# 假設 transaction_times 是一個包含所有交易時間戳記的 Series
transaction_times = pd.Series([...], dtype='datetime64[ns]')

# 計算每筆交易的總金額(假設有其他邏輯處理)
total_amounts = transaction_amounts.sum()

print(total_amounts)

這樣你就能高效地計算總金額並儲存結果。

錯誤教訓

在實務中,玄貓曾經遇到過一次重大錯誤。當時我們使用了不適當的整數型別來儲存超過範圍限制的值,導致資料被截斷且產生了意外結果。這次經驗提醒我們在選擇資料型別時要特別小心,確保選擇合適的範圍和精確度。

未來趨勢預測

隨著技術發展及硬體效能提升,未來可能會出現更多高效且靈活的整數型別管理方式。例如,Apache Arrow這類別專案正在推動跨語言和跨工具的標準化資料型別定義,這可能會改變我們處理和儲存整數資料的方式。

Conclusion

透過以上內容,我們瞭解瞭如何使用pandas中的整數型別來進行高效能運算及儲存。玄貓希望這些實務經驗和技術見解能夠幫助大家更好地掌握pandas工具並應用於實際工作中。

資料型別與資料結構

在大多數計算環境中,整數的寬度通常有 8、16、32 和 64 位元,而這些整數可以是帶號(signed)或不帶號(unsigned)。帶號表示數字可以是正或負,而不帶號則表示數字必須是非負的。以下表格總結了每種整數型別的範圍:

| 型別 | 最小值 | 最大值 | |




-|




|




| | 8 位元, 帶號 | -128 | 127 | | 8 位元, 不帶號 | 0 | 255 | | 16 位元, 帶號 | -32769 | 32767 | | 16 位元, 不帶號| 0 | 65535 | | 32 位元, 帶號 | -2147483648 | 2147483647 | | 32 位元, 不帶號| 0 | 4294967295 | | 64 位元, 帶號 | -2^63 | 2^63-1 | | 64 位元, 不帶號| 0 | 2^64-1 |

這些整數型別之間的權衡在於容量與記憶體使用。例如,64位元的整數型別所需的記憶體是8位元整數型別的8倍。這是否會成為問題,取決於資料集的大小和分析所使用的系統。

在 pandas 擴充套件型別系統中,這些整數型別的 dtype=引數分別使用 pd.IntXXDtype() 和 pd.UIntXXDtype(),其中 XX 指的是位元寬度。以下是一些範例:

pd.Series(range(555, 558), dtype=pd.Int16Dtype())
0    555
1    556
2    557
dtype: Int16
pd.Series(range(3), dtype=pd.UInt8Dtype())
0    0
1    1
2    2
dtype: UInt8

浮點數型別

浮點數型別允許表示實數,而不僅僅是整數。這意味著你可以處理一個連續且理論上無限大的值集合。浮點數計算在幾乎所有科學計算、宏觀財務分析和機器學習演算法中都會出現。

然而,浮點數型別仍有其限制,特別是在精確度和取捨誤差上。這意味著浮點數並不適合需要絕對精確度的情況。對於此類別需求,應該參考 PyArrow 小數型別。

儘管有這些限制,浮點數仍是表示分數數字的最常見資料型別。

要構建浮點數資料,可以使用 dtype=pd.Float64Dtype():

pd.Series([3.14, .333333333, -123.456], dtype=pd.Float64Dtype())
0     3.140000
1     0.333333
2   -123.456000
dtype: Float64

與整數型別相似,缺失值標記為 pd.NA:

pd.Series([3.14, None, pd.NA], dtype=pd.Float64Dtype())
0     3.140000
1          <NA>
2          <NA>
dtype: Float64

浮點數運算

由於設計上的原因,浮點數值本質上是不精確的,因此浮點數運算比整數運算更慢。這裡不探討浮點數運算的細節,但有興趣瞭解更多的人可以參考 Python 的官方檔案。

Python 本身內建了一個 float 型別,但這實際上是一個 IEEE-754 雙精確度浮點數。這個標準和其他語言如 C/C++ 一樣,有明確區分 float 和 double 型別,前者佔用了三十二位元而後者則佔用了六十四位元。

為了區分這些寬度但同時保持與 Python 名詞的一致性,pandas 提供了 pd.Float64Dtype() 和 pd.Float32Dtype()。

通常來說,除非系統資源受到限制,否則建議使用六十四位元浮點數型別。因為與三十二位元浮點數相比,六十四位元浮點數在精確度方面有顯著改進。實際上,三十二位元浮點數只能提供約六到九個十進位制小數位的精確度:

ser1 = pd.Series([1_000_000.123], dtype=pd.Float32Dtype())
ser2 = pd.Series([1_000_000.124], dtype=pd.Float32Dtype())
ser1.eq(ser2)
dtype: boolean

True

如果使用六十四位元浮點數型別,則可以得到約十五到十七個十進位制小數位的精確度。

布林值型別

布林值(Boolean)型別表示 True 或 False 的值。布林資料型別對於以「是/否」風格回答問題非常有用,並且廣泛應用於機器學習演算法中將分類別值轉換為電腦更容易處理的一和零(即 True 和 False)。

要建立布林值資料列(Series),應使用 dtype=pd.BooleanDtype

pd.Series([True, False, True], dtype=pd.BooleanDtype())
dtype: boolean

True
False
True

dtype: BooleanDtype()

pandas 函式庫會自動將值轉換為其布林表示形式:

pd.Series([1, None, pd.NA], dtype=pd.BooleanDtype())

dtype: BooleanDtype()

True

<NA>

<NA>

謂詞資料種類別

字串資料種類別適用於任何表示文字的資料。除非你處理的是純粹科學領域的資料集,否則字串在你所使用的資料中會非常常見。本文將強調 pandas 在處理字串資料時所提供的一些額外功能,特別是在 pd.Series.str 權杖方面。該權杖協助變更大小寫、提取子串和比對模式等操作。

技術細節:從 pandas version-版本開始(如版本為pandas-版本),字串處理會進行重大升級(如版本升級至v-版本),以實作更快速且需要較少記憶體資源管理功能。 要使此功能得以實作並進行進一步升級, 建議安裝 PyArrow 作為 pandas 的擴充套件。

要建立字串資料列(Series),應使用 dtype=pd.StringDtype()

pd.Series(["foo", "bar", "baz"], dtype=pd.StringDtype())

dtype: string

foo

bar

baz

dtype: StringDType()

玄貓一直建議使用 pd.NA 作為缺失指示符號:

pd.Series(["foo", None, pd.NA], dtype=pd.StringDType())

dtype: StringDType()

foo

<NA>

<NA>

此圖示展示了 Pandas 中不同資料種類別之間基本互換性及其應用場景:

graph TD;
    A[整數型別] --> B[範圍與精確度];
    B --> C[帶號與不帶號];
    A --> D[記憶體使用];
    D --> E[資料集大小];
    F[浮點數型別] --> G[實數表示];
    G --> H[連續數值];
    F --> I[計算精確度];
    I --> J[取捨誤差];
    K[布林型別] --> L[邏輯判斷];
    L --> M[機器學習];
    N[字串型別] --> O[文字表示];
    O --> P[文書處理功能];

內容解密:

上述圖示展示了 Pandas 中不同資料種類別之間基本互換性及其應用場景。 Pandas 提供了多種不同資料種類別來滿足不同需求:

  • 整數型別:適合需要處理具有固定範圍和精確度要求的資料。根據是否帶號或不帶號來選擇合適的範圍。
  • 浮點數型別:適合需要處理連續實數範圍和不需要絕對精確度要求的資料。
  • 布林型別:用於邏輯判斷和機器學習演算法中將分類別資料轉換為二進位制形式。
  • 謂詞種類別:適合文書處理及需要處理任意長度字串資料時使用。

Pandas 中不同資訊種類別之間存在著基本互換性:

  • 整數型別提供了不同寬度和符號選擇來滿足不同範圍和精確度要求。
  • 浮點數型別透過雙精確度浮點數來提高計算精確度。
  • 布林型別為邏輯判斷提供了簡單且高效的表示方式。
  • 謂詞種類別透過靈活性強大處理任何長度字串資料需求。

Pandas 中不同資訊種類別應用場景:

  • 整數型別通常應用於需求明確且範圍有限計算環境中。
  • 浮點數型別廣泛應用於科學計算、機器學習等連續數值運算中。
  • 布林型別在需要簡化判斷結果場景中常被使用。
  • 謂詞種類別主要應用於文書處理、自然語言處理等領域。

各種技術應用場景下需要選擇適合需求中的一種具體資訊種類別來進行運算與存取。

字串資料處理與缺失值處理

在使用 pandas 進行資料處理時,特別是處理字串資料與缺失值時,瞭解其內部機制及其對應的方法是非常重要的。本文將探討如何使用 pandas 的字串存取器來操作字串資料,並解釋其如何處理各種資料型別的缺失值。

字串資料處理

當我們使用 pd.Series 來儲存字串資料時,pandas 提供了一個稱為字串存取器的工具,這個工具能夠針對字串資料提供多種有用的方法。這些方法可以透過 pd.Series.str 來存取。

基本字串操作

以下是一些常見的字串操作範例:

import pandas as pd

# 建立一個包含字串的 pd.Series
ser = pd.Series(["xx", "YyY", "zZzZ"], dtype=pd.StringDtype())

# 取得每個字串的長度
ser.str.len()

內容解密:

此範例展示瞭如何建立一個包含字串的 pd.Series,並使用 str.len() 方法來取得每個字串的長度。str.len()pandas 提供的一個便利方法,用於計算每個字串的長度。

# 轉換所有字母為大寫
ser.str.upper()

內容解密:

此範例展示瞭如何將 pd.Series 中的所有字母轉換為大寫。這裡使用的是 str.upper() 方法,該方法會將每個字串中的所有小寫字母轉換為大寫。

# 轉換所有字母為小寫
ser.str.lower()

內容解密:

此範例展示瞭如何將 pd.Series 中的所有字母轉換為小寫。這裡使用的是 str.lower() 方法,該方法會將每個字串中的所有大寫字母轉換為小寫。

# 轉換為標題樣式(首字母大寫)
ser.str.title()

內容解密:

此範例展示瞭如何將 pd.Series 中的每個詞轉換為標題樣式(即首字母大寫)。這裡使用的是 str.title() 方法,該方法會將每個詞的第一個字母轉換為大寫。

檢查字串包含

pd.Series.str.contains 可以用來檢查每個元素是否包含指定的子串或符合特定正規表示式。

ser = pd.Series(["foo", "bar", "baz"], dtype=pd.StringDtype())

# 檢查是否包含子串 "o"
ser.str.contains("o")

內容解密:

此範例展示瞭如何使用 str.contains() 方法來檢查每個元素是否包含指定的子串 “o”。該方法會傳回一個布林型陣列,表示每個元素是否包含該子串。

# 檢查是否符合正規表示式 "^ba[rz]$"
ser.str.contains(r"^ba[rz]$", case=False, regex=True)

內容解密:

此範例展示瞭如何使用正規表示式來檢查每個元素是否符合特定模式。這裡使用的是 str.contains() 方法,並設定 regex=Truecase=False引數以進行不區分大小寫的正規表示式比對。這樣可以檢查每個元素是否符合正規表示式 “^ba[rz]$"。

漏失值處理

在進一步探討更多資料型別之前,我們需要了解 pandas 是如何處理缺失值的。儘管目前我們只見到過 pd.NA,但在更多型別中,缺失值處理可能會變得更加複雜。以下是一些關於缺失值處理的核心概念。

整數與浮點數之間的轉換

pandas 原本是建立在 NumPy 上的,而 NumPy 的預設資料型別並不支援缺失值。因此,pandas 需要自行構建缺失值處理機制。最初,它選擇使用 np.nan 作為缺失值標記。

import numpy as np

# 建立一個整數型 pd.Series
ser = pd.Series(range(3))

# 新增一個缺失值
ser.iloc[1] = None

內容解密:

此範例展示了當在整數型 pd.Series 中新增一個缺失值時會發生什麼情況。由於整數型別不支援缺失值,因此當我們新增一個缺失值後,整數型數列會自動轉換為浮點數型別以支援缺失值表示。

# 轉換後的 pd.Series
print(ser)

內容解密:

此範例展示了轉換後的結果:原本整數型的數列已經轉換為浮點數型別,以便能夠表示缺失值(NaN)。

不同資料型別中的漏失值

對於其他資料型別(如布林型別和日期時間型別),漏失值也有不同的處理方式:

  • 布林型別:當布林型別出現漏失值時,會被轉換為物件型別。
  • 日期時間型別:漏失值用特殊標記 pd.NaT 來表示。

漏失值檢查

無論使用哪種資料型別,pandas 提供了一個統一的函式來檢查缺失值:pd.isna()。這個函式可以檢測任何元素是否為漏失值。

# 檢查預設資料型別中的漏失值
print(pd.isna(pd.Series([1, np.nan, 2])))

內容解密:

此範例展示瞭如何使用 pd.isna() 函式來檢測預設資料型別中的漏失值。結果是一個布林型序列,指示每個元素是否為漏失值。

# 檢查擴充套件型別中的漏失值
print(pd.isna(pd.Series([1, pd.NA, 2], dtype=pd.Int64Dtype())))

內容解密:

此範例展示瞭如何使用 pd.isna() 函式來檢測擴充套件型別中的漏失值。結果同樣是一個布林型序列,指示每個元素是否為漏失值。

未來趨勢與實務應用

隨著技術不斷進步與演變,瞭解這些底層機制將有助於我們更好地編寫高效且穩健的程式碼。儘管目前存在一些歷史遺留問題(如不同資料型別間的不一致性),但掌握它們並能靈活應對將使我們在資料處理中更加遊刃有餘。未來可能會有更多改進和新功能出現,但基礎知識依然至關重要。

此外,「此圖示」說明瞭不同資料類別下的性質和形式:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 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

未來趨勢與實務應用

從這些觀察中可以看出不同資料形式下皆需考量其本身限制及擴增專案、全面思考程式邏輯及設計考量、充分理解技術原理及潛在改進點;也須具備充足閱歷及實務案例理解其合理性。