Pandas 資料型別
Pandas 的 DataFrame 中,每個欄位都有特定的資料型別(dtype)。了解和正確設定資料型別對於資料處理和記憶體效率很重要。
常見資料型別
| dtype | 說明 | 範例 |
|---|---|---|
int64 | 整數 | 1, 2, 3 |
float64 | 浮點數 | 1.5, 2.7 |
bool | 布林值 | True, False |
object | 字串或混合型別 | 'hello' |
datetime64 | 日期時間 | 2024-01-01 |
timedelta64 | 時間差 | 5 days |
category | 類別型 | 'A', 'B', 'C' |
查看資料型別
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'salary': [50000.0, 60000.0, 70000.0],
'is_active': [True, False, True]
})
# 查看所有欄位的型別
print(df.dtypes)
name object
age int64
salary float64
is_active bool
dtype: object
# 查看單一欄位的型別
print(df['age'].dtype) # int64
型別轉換
astype()
# 轉換成特定型別
df['age'] = df['age'].astype(float)
df['salary'] = df['salary'].astype(int)
# 同時轉換多個欄位
df = df.astype({'age': 'float64', 'salary': 'int64'})
常見轉換
# 整數轉浮點數
df['age'] = df['age'].astype(float)
# 浮點數轉整數(會截斷小數)
df['salary'] = df['salary'].astype(int)
# 數字轉字串
df['age'] = df['age'].astype(str)
# 字串轉數字
df['age'] = df['age'].astype(int)
# 轉布林值
df['is_active'] = df['is_active'].astype(bool)
轉換失敗的處理
df = pd.DataFrame({'value': ['1', '2', 'three', '4']})
# 直接轉換會報錯
# df['value'].astype(int) # ValueError
# 使用 pd.to_numeric 處理
df['value'] = pd.to_numeric(df['value'], errors='coerce') # 無法轉換變成 NaN
print(df)
value
0 1.0
1 2.0
2 NaN
3 4.0
errors 參數選項:
'raise':遇到錯誤就報錯(預設)'coerce':無法轉換的變成 NaN'ignore':忽略錯誤,保持原值
日期時間轉換
df = pd.DataFrame({
'date': ['2024-01-01', '2024-01-15', '2024-02-01']
})
# 轉換成 datetime
df['date'] = pd.to_datetime(df['date'])
print(df.dtypes)
# date datetime64[ns]
指定日期格式:
df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d')
# 處理不同格式
df['date'] = pd.to_datetime(df['date'], format='mixed')
類別型 (Categorical)
適合欄位值只有有限幾種的情況,可以節省記憶體:
df = pd.DataFrame({
'size': ['S', 'M', 'L', 'M', 'S', 'L', 'M']
})
# 轉換成類別型
df['size'] = df['size'].astype('category')
print(df['size'].dtype) # category
# 指定順序的類別
df['size'] = pd.Categorical(df['size'], categories=['S', 'M', 'L'], ordered=True)
選取特定型別的欄位
df = pd.DataFrame({
'name': ['Alice', 'Bob'],
'age': [25, 30],
'salary': [50000.0, 60000.0],
'is_active': [True, False]
})
# 選取數值型欄位
numeric_cols = df.select_dtypes(include=['number'])
# 選取字串欄位
string_cols = df.select_dtypes(include=['object'])
# 排除特定型別
non_numeric = df.select_dtypes(exclude=['number'])
記憶體優化
降低數值精度
# int64 -> int32 或 int16
df['age'] = df['age'].astype('int16')
# float64 -> float32
df['salary'] = df['salary'].astype('float32')
使用類別型取代字串
# 字串欄位佔用較多記憶體
df['city'] = df['city'].astype('category')
查看記憶體使用量
# 簡易版
print(df.memory_usage())
# 詳細版(包含字串的實際大小)
print(df.memory_usage(deep=True))
# 總記憶體(MB)
print(df.memory_usage(deep=True).sum() / 1024 / 1024)
自動推斷型別
# 讀取資料時自動推斷
df = pd.read_csv('data.csv')
# 重新推斷型別
df = df.infer_objects()
# 轉換字串欄位中的數字
df = df.convert_dtypes()
檢查型別
import numpy as np
# 檢查是否為數值型
print(np.issubdtype(df['age'].dtype, np.number)) # True
# 檢查是否為整數型
print(np.issubdtype(df['age'].dtype, np.integer)) # True
# 使用 pandas 的方法
print(pd.api.types.is_numeric_dtype(df['age'])) # True
print(pd.api.types.is_string_dtype(df['name'])) # True