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