Pandas 資料處理: 如何處理數據型態自動推斷的問題?

2024/03/06閱讀時間約 8 分鐘

前言

在最近處理資料的過程中,我使用了 pandas 這個強大的工具來操作結構化的表格資料,特別是 CSV 格式的檔案。我遇到了一個挑戰:當不特別指定資料型別時,Pandas 會自動根據欄位內容推斷最合適的資料型態,如浮點數(float)、字串(str)、物件(object)等。這種自動推斷雖然方便,但也可能引發問題,尤其是當我們對於特定欄位的型別有所預期,卻因為自動轉換而產生錯誤,尤其在後續的資料處理階段,錯誤的資料型態可能會被轉成字串進行進一步的操作,這不僅增加了錯誤的發生率,也可能改變資料原本的含義。

因此,本篇文章旨在探討在使用 pandas 處理資料時應注意的幾個關鍵點,以及思考是否存在更好的方法來處理這些資料,從而減少因資料型態問題而產生的錯誤,確保資料的原始意義得以保留。

raw-image

第一部分:Pandas 資料處理深入解析

1. 創造假資料

設定以下三個情境做實驗:

  • 欄位內容全部為數字
  • 數字和文字
  • 數字和 NA 值
import pandas as pd
import numpy as np

# 情境 1: 欄位全部為數字(譬如:ID號)
data1 = {
'ID': [1001, 1002, 1003, 1004],
'weight': [51.3, 30, 38.5, 92]
}

# 情境 2: 欄位包含數字和文字(譬如:產品編號和產品名稱)
data2 = {
'Product Code': ['001', '002', '003', 'A04'],
'Product Name': ['Table', 'Chair', 'Desk', 'Lamp']
}

# 情境 3: 欄位包含數字和 NA 值(譬如:員工的工作年數,未知值用 NA 代替)
data3 = {
'Employee Name': ['John Doe', 'Jane Smith', 'Emily Jones', 'Michael Brown'],
'Years of Service': [5, 8, np.nan, 2]
}

df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)
df3 = pd.DataFrame(data3)

# 儲存為 CSV 檔案
df1.to_csv('sample_data_scenario1.csv', index=False)
df2.to_csv('sample_data_scenario2.csv', index=False)
df3.to_csv('sample_data_scenario3.csv', index=False)
raw-image


2. Pandas 自動判讀的結果

三個資料案例分別的 data info ,在不指定型別的情況下,Pandas 自動判讀的結果:

  • df1: 兩個欄位分別是 int64 和 float64
raw-image
  • df2 : 兩個欄位都具有文字,所以都是 object
raw-image
  • df3: 一個欄位是文字,所以是 object ;
    另外一個欄位沒有文字只有 na 和數字,所以是 float64
raw-image


3.Pandas 讀取時指定型別

  • 所有統一個型別
raw-image
  • 依照各別欄位指定型別,用 dict 方式傳入,key 是 col name , value 是型別
raw-image


4. 讀取後做轉換 (小心使用)

有些狀況可行,但有些狀況會有問題這要特別小心

df3 = pd.read_csv('sample_data_scenario3.csv')
df3['Years of Service'] = df3['Years of Service'].astype('string')

這個情況型別就從 float 轉換成 string 了。

但是我稍微變形一下資料

raw-image

欄位中具有 na 、也有 float 、也有為 0 開頭的數字

如果要保留資料最原始的樣子,那 read 後再去轉型別的話就會改變資料內容

raw-image

原本第一列的 0005 ,就會變成 5.0 ,這樣就不太對,即使現在型別已經是 string 了!所以使用這個方法時要特別小心!


第二部分:尋找CSV之外的數據儲存方案

使用 CSV 檔案和 Pandas 時,數據型別自動轉換是一個常見的問題。CSV 是一種文本格式,不直接支持數據型別的元信息,這就導致了在讀取和寫入數據時可能會發生數據型別的不一致性問題。為了解決這個問題,可以考慮使用支持數據型別元信息的格式來存儲數據,比如 PickleNumPy 的二進制格式,或者使用更現代的數據格式如 ParquetHDF5。以下是這些方法的一些特點和使用示例:

1. 使用 Pickle 格式

Pickle 是 Python 的內建模塊,可以序列化和反序列化 Python 對象結構。使用 Pickle 格式可以保留數據的原始型別,但要注意,Pickle 是 Python 特有的,並且可能不是跨語言或長期數據存儲的最佳選擇。

# 將 DataFrame 存儲為 Pickle 文件
df.to_pickle('/path/to/your_data.pkl')

# 從 Pickle 文件讀取 DataFrame
df = pd.read_pickle('/path/to/your_data.pkl')

2. 使用 NumPy 的二進制格式

如果您的數據主要是數值型數據,可以考慮使用 NumPy 的二進制格式來存儲。這種格式適用於大型數值數據集,可以有效地保存和加載數據。

import numpy as np

# 將數據保存為 NumPy 的二進制格式
np.save('/path/to/your_data.npy', df.values)

# 從二進制文件加載數據
data = np.load('/path/to/your_data.npy')
df = pd.DataFrame(data, columns=['Column1', 'Column2']) # 需要手動指定列名

3. 使用 HDF5 格式

HDF5 是一種管理大型數據集的文件格式,支持多種類型的數據。它適合於大規模數據存儲和高效的隨機訪問。


import h5py
import numpy as np

with h5py.File('example.h5', 'w') as file:
dataset = file.create_dataset("dataset_name", (100,), dtype='i') data = np.arange(100)
dataset[:] = data

結論:優化資料處理策略,確保數據的正確性

透過本文的探討,我們深入了解了使用 Pandas 處理 CSV 文件時遇到的挑戰,特別是關於資料型態自動推斷的問題,以及如何透過指定資料型態或進行適當的資料轉換來避免潛在的錯誤。此外,我們也找尋了 CSV 格式以外的數據儲存選項,包括 pickle、numpy 和 hdf5,這些方法各有其優勢和適用場景,能夠在不同的應用中提供更高的效率和靈活性。

從模擬數據的創建到數據的最終儲存,每一步都需謹慎考慮資料處理的策略,以確保數據準確性和處理效率。自動型別推斷雖然提供了便捷,但也可能導致不可預見的錯誤,(尤其沒有仔細規劃跟設計時,隨機出現錯誤除錯很花時間),因此在處理數據時應明確指定資料型態或使用更加穩定的資料處理格式來避免這些問題。

此外,隨著數據量的增加和分析需求的提高,採用 hdf5 更高效的數據儲存格式變得越來越重要。這些格式不僅可以提高讀寫速度,還能在保存和處理大規模數據集時節省存儲空間。選擇最適合特定需求的資料處理和儲存方法,可以顯著提高資料分析的效率和正確性。


23會員
28內容數
歡迎來到《桃花源記》專欄。這裡不僅是一個文字的集合,更是一個探索、夢想和自我發現的空間。在這個專欄中,我們將一同走進那些隱藏在日常生活中的"桃花源"——那些讓我們心動、讓我們反思、讓我們找到內心平靜的時刻和地方
留言0
查看全部
發表第一個留言支持創作者!