讀取和寫入 CSV 檔案#

Arrow 支援從/向 CSV 檔案讀取和寫入欄狀資料。目前提供的功能如下:

  • 多執行緒或單執行緒讀取

  • 自動解壓縮輸入檔案(基於檔案名稱副檔名,例如 my_data.csv.gz

  • 從 CSV 檔案的第一列獲取欄名

  • 逐欄類型推斷和轉換為 nullint64float64date32time32[s]timestamp[s]timestamp[ns]stringbinary 資料之一

  • stringbinary 欄進行機會主義字典編碼(預設停用)

  • 偵測各種 null 值的拼寫方式,例如 NaN#N/A

  • 寫入 CSV 檔案,並提供選項來配置確切的輸出格式

用法#

CSV 讀取和寫入功能可透過 pyarrow.csv 模組取得。在許多情況下,您只需呼叫 read_csv() 函數,並提供您要從中讀取的檔案路徑即可

>>> from pyarrow import csv
>>> fn = 'tips.csv.gz'
>>> table = csv.read_csv(fn)
>>> table
pyarrow.Table
total_bill: double
tip: double
sex: string
smoker: string
day: string
time: string
size: int64
>>> len(table)
244
>>> df = table.to_pandas()
>>> df.head()
   total_bill   tip     sex smoker  day    time  size
0       16.99  1.01  Female     No  Sun  Dinner     2
1       10.34  1.66    Male     No  Sun  Dinner     3
2       21.01  3.50    Male     No  Sun  Dinner     3
3       23.68  3.31    Male     No  Sun  Dinner     2
4       24.59  3.61  Female     No  Sun  Dinner     4

若要寫入 CSV 檔案,只需使用 write_csv() 函數,並提供 pyarrow.RecordBatchpyarrow.Table 以及路徑或類檔案物件

>>> import pyarrow as pa
>>> import pyarrow.csv as csv
>>> csv.write_csv(table, "tips.csv")
>>> with pa.CompressedOutputStream("tips.csv.gz", "gzip") as out:
...     csv.write_csv(table, out)

注意

寫入器尚不支援所有 Arrow 類型。

自訂解析#

若要在讀取具有不尋常結構的 CSV 檔案時變更預設解析設定,您應該建立 ParseOptions 實例,並將其傳遞給 read_csv()

import pyarrow as pa
import pyarrow.csv as csv

table = csv.read_csv('tips.csv.gz', parse_options=csv.ParseOptions(
   delimiter=";",
   invalid_row_handler=skip_handler
))

可用的解析選項包括:

delimiter

在 CSV 資料中分隔個別儲存格的字元。

quote_char

選擇性地用於引用 CSV 值的字元(如果不允許引用,則為 False)。

double_quote

在引用的 CSV 值中,兩個引號是否表示資料中的單個引號。

escape_char

選擇性地用於跳脫特殊字元的字元(如果不允許跳脫,則為 False)。

newlines_in_values

是否允許 CSV 值中包含換行字元。

ignore_empty_lines

是否忽略 CSV 輸入中的空行。

invalid_row_handler

無效列的可選處理常式。

另請參閱

如需更多範例,請參閱 ParseOptions

自訂轉換#

若要變更 CSV 資料轉換為 Arrow 類型和資料的方式,您應該建立 ConvertOptions 實例,並將其傳遞給 read_csv()

import pyarrow as pa
import pyarrow.csv as csv

table = csv.read_csv('tips.csv.gz', convert_options=csv.ConvertOptions(
    column_types={
        'total_bill': pa.decimal128(precision=10, scale=2),
        'tip': pa.decimal128(precision=10, scale=2),
    }
))

可用的轉換選項包括:

check_utf8

是否檢查字串欄的 UTF8 有效性。

column_types

明確將欄名對應到欄類型。

null_values

表示資料中 null 值的字串序列。

true_values

表示資料中 true 布林值的字串序列。

false_values

表示資料中 false 布林值的字串序列。

decimal_point

在浮點數和十進位資料中用作小數點的字元。

timestamp_parsers

strptime() 相容格式字串的序列,在嘗試推斷或轉換時間戳記值時依序嘗試(也可以給定特殊值 ISO8601())。

strings_can_be_null

字串/二進位欄是否可以有 null 值。

quoted_strings_can_be_null

引用的值是否可以為 null。

auto_dict_encode

是否嘗試自動對字串/二進位資料進行字典編碼。

auto_dict_max_cardinality

auto_dict_encode 的最大字典基數。

include_columns

要包含在表格中的欄名。

include_missing_columns

如果為 false,則 include_columns 中的欄,但 CSV 檔案中沒有的欄將會發生錯誤。

另請參閱

如需更多範例,請參閱 ConvertOptions

增量讀取#

對於記憶體受限的環境,也可以一次讀取一個批次的 CSV 檔案,使用 open_csv()

有一些注意事項:

  1. 目前,增量讀取器始終是單執行緒的(無論 ReadOptions.use_threads 如何)

  2. 類型推斷會在第一個區塊上完成,之後類型會被凍結;為了確保推斷出正確的資料類型,可以將 ReadOptions.block_size 設定為夠大的值,或使用 ConvertOptions.column_types 明確地設定所需的資料類型。

字元編碼#

預設情況下,CSV 檔案應以 UTF8 編碼。非 UTF8 資料可接受用於 binary 欄位。可以使用 ReadOptions 類別來變更編碼

import pyarrow as pa
import pyarrow.csv as csv

table = csv.read_csv('tips.csv.gz', read_options=csv.ReadOptions(
   column_names=["animals", "n_legs", "entry"],
   skip_rows=1
))

可用的讀取選項如下

use_threads

是否使用多執行緒加速讀取。

block_size

每次從輸入流處理多少位元組。

skip_rows

在欄位名稱(如果有的話)和 CSV 資料之前要跳過的列數。

skip_rows_after_names

在欄位名稱之後要跳過的列數。

column_names

目標表格的欄位名稱。

autogenerate_column_names

如果 column_names 為空,是否自動產生欄位名稱。

encoding

encoding: object

另請參閱

更多範例請參閱 ReadOptions

自訂寫入#

若要變更預設的寫入設定,以處理使用不同慣例寫入 CSV 檔案的情況,您可以建立一個 WriteOptions 實例,並將其傳遞給 write_csv()

>>> import pyarrow as pa
>>> import pyarrow.csv as csv
>>> # Omit the header row (include_header=True is the default)
>>> options = csv.WriteOptions(include_header=False)
>>> csv.write_csv(table, "data.csv", options)

增量寫入#

若要一次寫入一個批次的 CSV 檔案,請建立一個 CSVWriter。這需要輸出(路徑或類檔案物件)、要寫入資料的結構描述,以及可選的寫入選項,如上所述

>>> import pyarrow as pa
>>> import pyarrow.csv as csv
>>> with csv.CSVWriter("data.csv", table.schema) as writer:
>>>     writer.write_table(table)

效能#

由於 CSV 檔案的結構,不能期望達到與讀取專用二進制格式(如 Parquet)相同的效能水平。儘管如此,Arrow 致力於減少讀取 CSV 檔案的開銷。合理的期望是在高效能桌上型電腦或筆記型電腦上,每個核心至少達到 100 MB/s 的速度(以來源 CSV 位元組測量,而不是目標 Arrow 資料位元組)。

效能選項可以透過 ReadOptions 類別進行控制。多執行緒讀取是預設設定,以實現最高效能,有效地將工作負載分配到所有可用的核心上。

注意

並行執行緒的數量由 Arrow 自動推斷。您可以使用 cpu_count()set_cpu_count() 函數來檢查和變更它。