HOWTO · NumPy

在 Python 中將 NumPy 陣列寫入 CSV

本教程演示如何將 numpy 陣列儲存在 csv 檔案中

本頁內容

使用 numpy.savetxt() 可將數值型 NumPy 陣列寫成以逗號分隔的文字。若陣列已屬於 DataFrame 工作流程,或需要建立、調整資料列,可改用 pandas 或 csv.writer。CSV 以資料列和欄位表示資料,因此儲存前應先決定一維或更高維度的陣列要如何對應到這些資料列與欄位。

範例使用含整數值的小型二維陣列,輸出只包含數值,不含標頭或索引。陣列範例需要 NumPy;pandas 是額外套件,只有 pandas 範例需要安裝。範例中的程式碼與顯示輸出保留英文;輸出標籤也維持英文。

根據陣列和所需輸出選擇方法

若要將數值陣列寫入簡單的分隔文字檔,numpy.savetxt() 是直接的預設選擇。delimiter 用來設定分隔符號,fmt 則決定每個值的呈現格式。若已需要 DataFrame 操作或欄位標籤,可使用 pandas;若資料列需要自訂處理,或需要 Python 的 CSV 引號規則,則可使用 csv.writer。相較於自行將值串接成字串,內建的寫入器更能安全處理欄位中的逗號和引號。

numpy.savetxt() 會將一維陣列視為欄向量,因此每行寫入一個值。若要把這些值寫在同一個 CSV 資料列中,請先將陣列重塑為 (1, -1) 再儲存。下方的 csv.writer 迴圈假設輸入是二維陣列:每次迭代得到的 row 本身都是可迭代物件。一維輸入若要寫成單一資料列,可使用 writer.writerow(data);若要每個值各占一列,則逐一迭代數值並呼叫 writer.writerow([value])。CSV 沒有原生的三維資料表示方式。請將 3D 陣列重塑成列與欄,或將其攤平,並選擇讀取端能還原的順序。不要讓攤平操作在未明確決定的情況下替你決定資料布局。

使用 numpy.savetxt() 儲存 NumPy 陣列

範例中的整數值適合使用 '%d' 格式。若資料是浮點數,且小數點後三位已足夠,可選用 '%.3f' 等格式;格式化可能會將數值四捨五入,因此請依照需要保留的精度選擇格式。若接收工具需要不同分隔符號,也可將 ';' 或 '\t' 等值傳給 delimiter。

以下範例將二維整數陣列寫成以逗號分隔的數值文字。程式碼與顯示輸出保持英文原樣,輸出標籤也不翻譯。

執行此範例:

本節中的程式碼以及顯示的標籤或輸出仍為英文。

from pathlib import Path
from tempfile import TemporaryDirectory
import numpy as np

data = np.array([[1, 2, 3], [4, 5, 6]])
with TemporaryDirectory() as directory:
    path = Path(directory) / "array.csv"
    np.savetxt(path, data, delimiter=",", fmt="%d")
    print(path.read_text(), end="")
1,2,3
4,5,6

使用 pandas 儲存 NumPy 陣列

先將陣列轉換成 DataFrame,再呼叫 to_csv()。pandas 預設會寫入 DataFrame 索引和欄名;若檔案只應包含陣列值,請設定 index=False 和 header=False。若索引或欄名是提供給接收者的重要標籤,則保留或自行指定這些欄位。範例中的程式碼與顯示輸出保留英文,輸出標籤也維持英文。

本節中的程式碼以及顯示的標籤或輸出仍為英文。

from pathlib import Path
from tempfile import TemporaryDirectory
import numpy as np
import pandas as pd

data = np.array([[1, 2, 3], [4, 5, 6]])
with TemporaryDirectory() as directory:
    path = Path(directory) / "array.csv"
    pd.DataFrame(data).to_csv(path, index=False, header=False)
    print(path.read_text(), end="")
1,2,3
4,5,6

使用 Python 的 csv 模組寫入資料列

csv.writer 會寫入每個可迭代的資料列,並在 CSV 語法需要時逸出欄位內容。開啟檔案時請使用 newline="";如此可讓 CSV 模組管理換行字元,並避免在會轉換換行符號的平台上多出空白行。下方範例直接使用陣列中的資料列。程式碼與顯示輸出保留英文,輸出標籤也不翻譯。

本節中的程式碼以及顯示的標籤或輸出仍為英文。

from pathlib import Path
from tempfile import TemporaryDirectory
import csv
import numpy as np

data = np.array([[1, 2, 3], [4, 5, 6]])
with TemporaryDirectory() as directory:
    path = Path(directory) / "array.csv"
    with path.open("w", newline="", encoding="utf-8") as file:
        writer = csv.writer(file)
        for row in data:
            writer.writerow(row)
    print(path.read_text(), end="")
1,2,3
4,5,6

若要附加資料列,請以附加模式 ("a") 開啟目的檔案,並且只寫入新資料列。請確認新資料列的欄位順序和數量與既有內容一致;附加模式不會替你驗證資料,也不會新增標頭。一維輸入應先決定代表單一資料列,還是每個值各占一列,再依需求重塑陣列或將值包裝成適當形式。

了解 ndarray.tofile() 的限制

ndarray.tofile() 是陣列的方法,但不是 CSV 寫入器。它會依攤平後的順序寫入陣列元素,不會保留原始形狀或列與欄的結構。使用逗號分隔可產生分隔文字,但檔案仍無法告知讀取者原始維度。輸出的表示方式也取決於所選格式;只有一行本身並不代表數值精度已經流失。需要明確 CSV 布局時,請優先使用 savetxt、pandas 或 csv.writer。範例中的程式碼與顯示內容保留英文,標籤也維持英文。

僅對簡單資料手動撰寫 CSV 文字

若是小型、已知形狀且只含簡單數值的二維陣列,可以直接使用 Python 字串格式化來建立資料列。這種做法假設陣列的形狀和值適合以純文字表示。使用 join 建立完整輸出字串時,所需記憶體會隨輸出大小增加;此外,手動串接也不會依照 CSV 規則處理含逗號、引號或換行的值。一般資料或文字欄位請使用 csv.writer。範例中的程式碼與顯示輸出保留英文,輸出標籤也維持英文。

本節中的程式碼以及顯示的標籤或輸出仍為英文。

from pathlib import Path
from tempfile import TemporaryDirectory

data = [[1, 2, 3], [4, 5, 6]]
with TemporaryDirectory() as directory:
    path = Path(directory) / "array.csv"
    content = "\n".join(",".join(str(value) for value in row) for row in data)
    path.write_text(content + "\n", encoding="utf-8")
    print(path.read_text(), end="")
1,2,3
4,5,6