在 Python 中使用 NumPy 進行檔案的讀取與寫入
封面圖片是 NumPy 的官方 Logo , 2025 年 2 月 26 日擷取自 Github 。
前言
提到 Python 中的數值、矩陣運算,我們不得不提受到大多數程式設計者歡迎的 NumPy 模組。 NumPy 支援高維度、大規模的多維陣列與矩陣運算,並針對陣列運算提供大量的數學函式函式庫,使得在 Python 中進行數值運算時更加快速與容易。較可惜的是 NumPy 只能在 CPU 運行,無法利用 GPU 加速運算。
本文僅介紹 NumPy 的檔案讀取與寫入,有關 NumPy 的其他功能請參考其他文章或參考官方文件 https://numpy.org/doc/stable/reference/ 。
支援的檔案格式
NumPy 以二進制模式 (binary mode) 讀寫檔案,支援將資料寫入二進制格式檔案及純文字格式檔案。常見的格式有 NumPy 專用的二進制格式 .npy
、 .npz
,二進制格式 .bin
,純文字格式檔案 .txt
、 .csv
等。
.npy
格式
.npy
格式是用於儲存與載入 NumPy 的陣列類別 ndarray
的資料、形狀 (shape
)、資料類型 (dtype
) 等資訊。由於 .npy
檔案是單個數組儲存格式,因此只能儲存一個 NumPy 陣列。但因為 .npy
檔案採用二進制格式進行儲存,故比 .txt
、 .csv
等格式更節省空間,讀取速度更快。
.npz
格式
.npz
格式與 .npy
格式具有相同功能。不同的是 .npz
格式可以用來儲存多個 NumPy 陣列,且可以使用 .savez_compressed()
將資料進行壓縮。
.bin
格式
.bin
格式雖然也是二進制格式,但與 .npy
格式不同的是,.bin
格式只儲存資料,不儲存資料的形狀及資料類型。因此,在讀取 .bin
格式時總是需要手動指定資料的形狀。
寫入檔案
NumPy 將數值、矩陣寫入檔案的語法有很多種,以下介紹 .save()
、 .savez()
、 .savez_compressed()
、 .savetxt()
、 .tofile()
等方法。
我們首先載入 NumPy 模組,並假設有兩 Numpy 陣列,分別為 arr1
和 arr2
。
|
|
.save()
適用於:
- 將單個陣列儲存為 NumPy 的
.npy
二進制格式。
用法:
.save(file, arr, allow_pickle=True)
參數:
file
: 要儲存的檔案名稱、字串或檔案路徑。arr
: 要儲存的陣列。allow_pickle
: 布林值,可選填。允許使用 Python pickle 儲存物件陣列,但並非所有 pickle 資料都相容於不同版本的 Python。預設為True
。
範例程式:
|
|
.savez()
適用於:
- 將多個陣列以未壓縮的格式儲存到
.npz
的單一檔案中。
用法:
.savez(file, *args, allow_pickle=True, **kwds)
參數:
file
: 要儲存的檔案名稱、字串或檔案路徑。args
: 要儲存的陣列,可選填。請使用下方的kwds
為每個陣列指定名稱,若使用args
儲存陣列,則預設名稱為"arr_0"
、"arr_1"
等等。allow_pickle
: 布林值,可選填。允許使用 Python pickle 儲存物件陣列,但並非所有 pickle 資料都相容於不同版本的 Python。預設為True
。kwds
: 要儲存的陣列,可選填。每個陣列將與其對應的自定義名稱一起儲存到輸出的檔案中。
範例程式:
|
|
.savez_compressed()
適用於:
- 將多個陣列以壓縮的格式儲存到
.npz
的單一檔案中。
用法:
.savez_compressed(file, *args, allow_pickle=True, **kwds)
參數:
file
: 要儲存的檔案名稱、字串或檔案路徑。args
: 要儲存的陣列,可選填。請使用下方的kwds
為每個陣列指定名稱,若使用args
儲存陣列,則預設名稱為"arr_0"
、"arr_1"
等等。allow_pickle
: 布林值,可選填。允許使用 Python pickle 儲存物件陣列,但並非所有 pickle 資料都相容於不同版本的 Python。預設為True
。kwds
: 要儲存的陣列,可選填。每個陣列將與其對應的自定義名稱一起儲存到輸出的檔案中。
範例程式:
|
|
.savetxt()
適用於:
- 將陣列儲存為純文字檔案 (
.txt
、.csv
) 。
用法:
.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='', comments='# ', encoding=None)
參數:
fname
: 要儲存的檔案名稱、字串或檔案路徑。如果副檔名為.gz
,則將自動儲存為 gzip 壓縮格式,.loadtxt()
也會自動解壓縮讀取 gzip 壓縮檔案。X
: 要儲存到純文字檔案的一維或二維陣列。fmt
: 字串或字串序列,可選填。此參數較複雜,請參考原始文件 https://numpy.org/doc/stable/reference/generated/numpy.savetxt.html 。delimiter
: 資料間的分隔符號,用於分隔每一列。可為字串或字元,可選填。newline
: 換行符號,用於分隔每一行。可為字串或字元,可選填。header
: 寫在檔案開頭的字串。footer
: 寫在檔案末端的字串。comments
: 寫在header
與footer
前的註解符號,預設為"# "
。encoding
:None
或字串,可選填。 NumPy 對輸出的檔案編碼進行的編碼,預設為"latin1"
。
範例程式:
|
|
.tofile()
適用於:
- 以二進制或純文字格式儲存,預設為二進制格式。
用法:
.tofile(fid, sep='', format='%s')
參數:
fid
: 要儲存的檔案名稱、字串或檔案路徑。sep
: 字串,資料間的分隔符號。format
: 字串,文字檔案輸出的格式字串。
範例程式:
|
|
讀取檔案
以下介紹使用 .load()
、 .loadtxt()
、 .genfromtxt()
、 .fromregex()
、 .fromstring()
、 .fromfile()
等方法將檔案讀取到 NumPy 中。
我們首先載入 NumPy 模組。
|
|
.load()
適用於:
- 從
.npy
、.npz
或 pickle 檔案讀取陣列或 pickle 物件。
用法:
.load(file, mmap_mode=None, allow_pickle=False, fix_imports=True, encoding='ASCII', *, max_header_size=10000)
參數:
file
: 要讀取的檔案名稱、字串或檔案路徑。mmap_mode
:None
、r+
、r
、w+
或c
,可選填。此參數較複雜,請參考原始文件 https://numpy.org/doc/stable/reference/generated/numpy.load.html 。allow_pickle
: 布林值,可選填。是否允許載入儲存在.npy
檔案中的 pickle 物件陣列。預設為False
。fix_imports
: 布林值,可選填。僅在 Python 3 上載入 Python 2 產生的 pickle 檔案時有用。encoding
:"latin1"
、"ASCII"
或"bytes"
,可選填。讀取 Python 2 字串時使用的編碼,預設"ASCII"
。max_header_size
: 整數,可選填。允許的最大header
大小。較大的header
可能不安全,導致無法安全載入。
範例程式:
|
|
.loadtxt()
適用於:
- 讀取純文字檔案。
用法:
.loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding=None, max_rows=None, *, quotechar=None, like=None)
參數:
fname
: 要讀取的檔案名稱、字串、檔案路徑或生成器 (generator) 。如果副檔名為.gz
,會自動解壓縮讀取 gzip 壓縮檔案。dtype
: 資料類型,可選填。預設為float
。comments
: 註解符號,字串或None
,可選填。預設為"# "
。delimiter
: 分隔符號,字串,可選填。預設為空格。converters
: 字典 (dict) ,可選填。預設為None
。skiprows
: 跳過前skiprows
行,包括註解。預設為 0 。usecols
: 要讀取哪些列,整數,可選填。 0 表示第一列,以此類推。預設為None
,表示讀取所有欄位。unpack
: 布林值,可選填。為True
時傳回的陣列將被轉置。預設為False
。ndmin
: 整數,可選填。陣列至少有 ndmin 個維度,有效值為 0(預設)、 1 或 2 。encoding
: 字串,可選填。預設為None
。此參數較複雜,請參考原始文件 https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html 。max_rows
: 整數,可選填。在skiprows
行之後讀取max_rows
行的內容,但不包含空行。quotechar
: unicode 字元或None
,可選填。引用項目的開始和結束的字元,預設為None
。like
: array_like 類別,可選填。建議參考原始文件 https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html 。
範例程式:
|
|
.genfromtxt()
適用於:
- 從純文字檔案載入資料,並以指定方式處理缺失值。
用法:
.genfromtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, skip_header=0, skip_footer=0, converters=None, missing_values=None, filling_values=None, usecols=None, names=None, excludelist=None, deletechars=" !#$%&'()*+, -./:;<=>?@[\\]^{|}~", replace_space='_', autostrip=False, case_sensitive=True, defaultfmt='f%i', unpack=None, usemask=False, loose=True, invalid_raise=True, max_rows=None, encoding=None, *, ndmin=0, like=None)
參數:
fname
: 要讀取的檔案名稱、字串、檔案路徑或生成器 (generator) 。如果副檔名為.gz
或.bz2
,會自動解壓縮讀取該壓縮檔案。dtype
: 資料類型,可選填。預設為float
。comment
: 註解符號,字串,可選填。delimiter
: 分隔符號,字串、整數或序列,可選填。skip_header
: 整數,可選填。檔案開頭要跳過的行數。skip_footer
: 整數,可選填。檔案末端要跳過的行數。converters
: 變數,可選填。將列的資料轉換為值的一組函數,也可為缺失資料提供預設值。missing_values
: 變數,可選填。對應到缺失資料的字串。filling_values
: 變數,可選填。缺失資料的預設值。usecols
: 要讀取哪些列,整數,可選填。 0 表示第一列,以此類推。預設為None
,表示讀取所有欄位。names
:None
、True
、字串或序列,可選填。如果為True
,將從skip_header
行之後的第一行讀取欄位名稱。excludelist
: 序列,可選填。要從names
排除的的清單。deletechars
: 字串,可選填。定義要從names
中刪除的無效字元清單。replace_space
: 字元,可選填。替換變數名稱中空格的字元,預設為"_"
。autostrip
: 布林值,可選填。是否自動從變數中去除空格。case_sensitive
:True
、False
、"upper"
或"lower"
,可選填。如果為True
,則欄位名稱區分大小寫。如果為False
或"upper"
,則欄位名稱將轉換為大寫。如果為"lower"
,則欄位名稱將轉換為小寫。defaultfmt
: 字串,可選填。定義預設欄位名稱的格式。unpack
: 布林值,可選填。為True
時傳回的陣列將被轉置。預設為False
。usemask
: 布林值,可選填。為True
時,回傳一個 masked 陣列。為False
時,則回傳一個 regular 陣列。loose
: 布林值,可選填。為True
時,不會因無效值而引發錯誤。invalid_raise
: 布林值,可選填。為True
時,偵測到列數不一致時會引發異常。為False
時,會發出警告並跳過有問題的行。max_rows
: 整數,可選填。要讀取的最大行數,不能與skip_footer
同時使用,且值必須至少為 1。encoding
: 字串,可選填。用於解碼輸入檔案的編碼,預設為None
。ndmin
: 整數,可選填。陣列至少有 ndmin 個維度,有效值為 0(預設)、 1 或 2 。like
: array_like 類別,可選填。建議參考原始文件 https://numpy.org/doc/stable/reference/generated/numpy.genfromtxt.html 。
範例程式:
|
|
.fromregex()
適用於:
- 從符合正則表達式的純文字檔案讀取陣列。
用法:
.fromregex(file, regexp, dtype, encoding=None)
參數:
file
: 要讀取的檔案名稱、字串或檔案路徑。regexp
: 字串或或 regexp ,用於解析檔案的正則表達式。dtype
: 資料類型 (dtype) 或資料類型的列表。encoding
: 字串,可選填。用於解碼輸入檔案的編碼。
範例程式:
|
|
.fromstring()
適用於:
- 從字串中的文字資料初始化為一個新的陣列。
用法:
.fromstring(string, dtype=float, count=-1, *, sep, like=None)
參數:
string
: 包含資料的字串。dtype
: 資料類型,可選填。預設為float
。count
: 整數,可選填。從string
中讀取count
個元素。如果count
為負數,將讀取整個string
。sep
: 分隔符號,字串,可選填。like
: array_like 類別,可選填。建議參考原始文件 https://numpy.org/doc/stable/reference/generated/numpy.fromstring.html 。
範例程式:
|
|
.fromfile()
適用於:
- 從純文字檔案或二進制格式檔案中的資料建立陣列。
用法:
.fromfile(file, dtype=float, count=-1, sep='', offset=0, *, like=None)
參數:
file
: 要讀取的檔案名稱、字串或檔案路徑。dtype
: 資料類型,可選填。count
: 要讀取的數量, -1 表示全部。sep
: 分隔符號,如果為純文字檔案,為""
。offset
: 整數。相對於檔案目前位置的偏移量,預設為 0 。like
: array_like 類別,可選填。建議參考原始文件 https://numpy.org/doc/stable/reference/generated/numpy.fromfile.html 。
範例程式:
|
|
結語
想要徹底了解 NumPy 的輸入與輸出是一項大工程,這裡面也不乏許多我看不懂或根本沒用過的指令、參數。透過學習上述的指令,我想,我應該對於 NumPy 有著多一點的認識了吧?
參考資料
plusone(2018年1月6日)。[Day18]Numpy檔案輸入與輸出!IT邦幫忙。2025年2月27日參考自 https://ithelp.ithome.com.tw/articles/10196167
為自己coding(2021年4月22日)。給自己的Python小筆記 - Numpy如何讀寫檔案? - NumPy獨有的npy和npz二進制檔案格式和text(.txt)檔案格式 - 讀取/寫入教學。Matters。2025年2月27日參考自 https://matters.town/a/k50fv7lzpioq
Ashe child 由羔羊(2021年6月28日)。Python: NumPy 的二進制檔案 .npy。羔羊的實驗紀錄簿。2025年2月27日參考自 https://yang10001.yia.app/2021/06/28/python:-numpy-的二進制檔案-npy/
NumPy(2024年11月30日)。維基百科,自由的百科全書。2025年2月27日參考自 https://zh.wikipedia.org/zh-tw/NumPy
Input and Output(2024年)。NumPy。2025年2月27日參考自 https://numpy.org/doc/stable/reference/routines.io.html
NumPy(2025年2月27日)。Github。2025年2月27日參考自 https://github.com/numpy/numpy