檔案系統介面#
PyArrow 隨附抽象檔案系統介面,以及各種儲存類型的具體實作。
檔案系統介面提供輸入和輸出串流以及目錄操作。公開了底層資料儲存的簡化視圖。資料路徑表示為抽象路徑,即使在 Windows 上也是以 /
分隔,並且不應包含特殊路徑組件,例如 .
和 ..
。符號連結(如果底層儲存支援)會自動取消引用。僅提供關於檔案條目的基本metadata
(例如檔案大小和修改時間)。
核心介面由基底類別 FileSystem
表示。
Pyarrow 原生實作了以下檔案系統子類別
也可以將您自己的 fsspec 相容檔案系統與 pyarrow 功能一起使用,如 搭配 Arrow 使用 fsspec 相容檔案系統 章節所述。
用法#
實例化檔案系統#
FileSystem 物件可以使用建構函式之一建立(並檢查各自建構函式的選項)
>>> from pyarrow import fs
>>> local = fs.LocalFileSystem()
或從 URI 推斷
>>> s3, path = fs.FileSystem.from_uri("s3://my-bucket")
>>> s3
<pyarrow._s3fs.S3FileSystem at 0x7f6760cbf4f0>
>>> path
'my-bucket'
讀取和寫入檔案#
PyArrow 中多個與 IO 相關的函數接受 URI(並推斷檔案系統)或明確的 filesystem
引數,以指定要從哪個檔案系統讀取或寫入。例如,pyarrow.parquet.read_table()
函數可以用以下方式使用
import pyarrow.parquet as pq
# using a URI -> filesystem is inferred
pq.read_table("s3://my-bucket/data.parquet")
# using a path and filesystem
s3 = fs.S3FileSystem(..)
pq.read_table("my-bucket/data.parquet", filesystem=s3)
檔案系統介面進一步允許直接開啟檔案進行讀取(輸入)或寫入(輸出),這可以與處理檔案類物件的函數結合使用。例如
import pyarrow as pa
local = fs.LocalFileSystem()
with local.open_output_stream("test.arrow") as file:
with pa.RecordBatchFileWriter(file, table.schema) as writer:
writer.write_table(table)
列出檔案#
可以使用 FileSystem.get_file_info()
方法檢查檔案系統上的目錄和檔案。若要列出目錄的內容,請使用 FileSelector
物件指定選取
>>> local.get_file_info(fs.FileSelector("dataset/", recursive=True))
[<FileInfo for 'dataset/part=B': type=FileType.Directory>,
<FileInfo for 'dataset/part=B/data0.parquet': type=FileType.File, size=1564>,
<FileInfo for 'dataset/part=A': type=FileType.Directory>,
<FileInfo for 'dataset/part=A/data0.parquet': type=FileType.File, size=1564>]
這會傳回 FileInfo
物件的列表,其中包含關於類型(檔案或目錄)、大小、上次修改日期等的資訊。
您也可以取得單個明確路徑(或路徑列表)的此資訊
>>> local.get_file_info('test.arrow')
<FileInfo for 'test.arrow': type=FileType.File, size=3250>
>>> local.get_file_info('non_existent')
<FileInfo for 'non_existent': type=FileType.NotFound>
本機 FS#
LocalFileSystem
允許您存取本機上的檔案。
如何寫入磁碟並讀回的範例
>>> from pyarrow import fs
>>> local = fs.LocalFileSystem()
>>> with local.open_output_stream('/tmp/pyarrowtest.dat') as stream:
stream.write(b'data')
4
>>> with local.open_input_stream('/tmp/pyarrowtest.dat') as stream:
print(stream.readall())
b'data'
S3#
PyArrow 原生實作了與 S3 相容儲存空間的 S3 檔案系統。
S3FileSystem
建構函式具有多個選項來配置 S3 連線(例如憑證、區域、端點覆寫等)。此外,建構函式還將檢查 AWS 支援的已配置 S3 憑證(例如 AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
環境變數、AWS 組態檔以及 EC2 節點的 EC2 執行個體中繼資料服務)。
如何從 S3 儲存貯體讀取內容的範例
>>> from pyarrow import fs
>>> s3 = fs.S3FileSystem(region='eu-west-3')
# List all contents in a bucket, recursively
>>> s3.get_file_info(fs.FileSelector('my-test-bucket', recursive=True))
[<FileInfo for 'my-test-bucket/File1': type=FileType.File, size=10>,
<FileInfo for 'my-test-bucket/File5': type=FileType.File, size=10>,
<FileInfo for 'my-test-bucket/Dir1': type=FileType.Directory>,
<FileInfo for 'my-test-bucket/Dir2': type=FileType.Directory>,
<FileInfo for 'my-test-bucket/EmptyDir': type=FileType.Directory>,
<FileInfo for 'my-test-bucket/Dir1/File2': type=FileType.File, size=11>,
<FileInfo for 'my-test-bucket/Dir1/Subdir': type=FileType.Directory>,
<FileInfo for 'my-test-bucket/Dir2/Subdir': type=FileType.Directory>,
<FileInfo for 'my-test-bucket/Dir2/Subdir/File3': type=FileType.File, size=10>]
# Open a file for reading and download its contents
>>> f = s3.open_input_stream('my-test-bucket/Dir1/File2')
>>> f.readall()
b'some data'
請注意,為正在使用的儲存貯體配置正確的區域來配置 S3FileSystem
非常重要。如果未設定 region
,AWS SDK 將選擇一個值,如果 SDK 版本 <1.8,則預設為 'us-east-1'。否則,它將嘗試使用各種啟發式方法(環境變數、組態設定檔、EC2 中繼資料伺服器)來解析區域。
也可以使用 pyarrow.fs.resolve_s3_region()
或 pyarrow.fs.S3FileSystem.from_uri()
從 S3FileSystem
的儲存貯體名稱解析區域。
以下是一些程式碼範例
>>> from pyarrow import fs
>>> s3 = fs.S3FileSystem(region=fs.resolve_s3_region('my-test-bucket'))
# Or via URI:
>>> s3, path = fs.S3FileSystem.from_uri('s3://[access_key:secret_key@]bucket/path]')
疑難排解#
使用 S3FileSystem
時,僅針對嚴重錯誤或列印傳回值產生輸出。為了進行疑難排解,可以使用環境變數 ARROW_S3_LOG_LEVEL
設定日誌層級。必須在執行任何與 S3 互動的程式碼之前設定日誌層級。可能的值包括 FATAL
(預設值)、ERROR
、WARN
、INFO
、DEBUG
(建議)、TRACE
和 OFF
。
Google 雲端儲存空間檔案系統#
PyArrow 原生實作了 Google 雲端儲存空間 (GCS) 後端檔案系統,用於 GCS 儲存空間。
如果未在 Google Cloud Platform (GCP) 上執行,這通常需要環境變數 GOOGLE_APPLICATION_CREDENTIALS
指向包含憑證的 JSON 檔案。或者,使用 gcloud
CLI 在預設位置產生憑證檔案
gcloud auth application-default login
若要連線到公用儲存貯體而不使用任何憑證,您必須將 anonymous=True
傳遞給 GcsFileSystem
。否則,檔案系統將報告 Couldn't resolve host name
,因為經過驗證和公用存取的主機名稱不同。
範例顯示如何從 GCS 儲存貯體讀取內容
>>> from datetime import timedelta
>>> from pyarrow import fs
>>> gcs = fs.GcsFileSystem(anonymous=True, retry_time_limit=timedelta(seconds=15))
# List all contents in a bucket, recursively
>>> uri = "gcp-public-data-landsat/LC08/01/001/003/"
>>> file_list = gcs.get_file_info(fs.FileSelector(uri, recursive=True))
# Open a file for reading and download its contents
>>> f = gcs.open_input_stream(file_list[0].path)
>>> f.read(64)
b'GROUP = FILE_HEADER\n LANDSAT_SCENE_ID = "LC80010032013082LGN03"\n S'
另請參閱
GcsFileSystem
建構函式預設使用 GCS 文件中描述的程序來解析憑證。
Hadoop 分散式檔案系統 (HDFS)#
PyArrow 帶有 Hadoop 檔案系統的綁定 (基於使用 libhdfs
的 C++ 綁定,一個基於 JNI 的介面,連接到 Java Hadoop client)。您可以使用 HadoopFileSystem
建構函式來連接
from pyarrow import fs
hdfs = fs.HadoopFileSystem(host, port, user=user, kerb_ticket=ticket_cache_path)
libhdfs
函式庫是在執行階段載入的 (而不是在連結 / 函式庫載入時期,因為該函式庫可能不在您的 LD_LIBRARY_PATH 中),並且依賴於一些環境變數。
HADOOP_HOME
:您安裝的 Hadoop 發行版的根目錄。通常包含lib/native/libhdfs.so
。JAVA_HOME
:您的 Java SDK 安裝位置。ARROW_LIBHDFS_DIR
(選填):libhdfs.so
的明確位置,如果它安裝在$HADOOP_HOME/lib/native
以外的其他地方。CLASSPATH
:必須包含 Hadoop jar 檔。您可以使用以下方式設定這些:export CLASSPATH=`$HADOOP_HOME/bin/hadoop classpath --glob` # or on Windows %HADOOP_HOME%/bin/hadoop classpath --glob > %CLASSPATH%
與使用
pa.hdfs.connect
的舊有 HDFS 檔案系統不同,設定CLASSPATH
不是選填的 (pyarrow 不會嘗試推斷它)。
將與 fsspec 相容的檔案系統與 Arrow 搭配使用#
上述提及的檔案系統由 Arrow C++ / PyArrow 原生支援。然而,Python 生態系統也有幾個檔案系統套件。那些遵循 fsspec 介面的套件也可以在 PyArrow 中使用。
接受檔案系統物件的函式也將接受 fsspec 子類別。例如
# creating an fsspec-based filesystem object for Google Cloud Storage
import gcsfs
fs = gcsfs.GCSFileSystem(project='my-google-project')
# using this to read a partitioned dataset
import pyarrow.dataset as ds
ds.dataset("data/", filesystem=fs)
Azure Blob Storage 也類似
import adlfs
# ... load your credentials and configure the filesystem
fs = adlfs.AzureBlobFileSystem(account_name=account_name, account_key=account_key)
import pyarrow.dataset as ds
ds.dataset("mycontainer/data/", filesystem=fs)
在底層,fsspec 檔案系統物件被包裝成一個基於 python 的 PyArrow 檔案系統 (PyFileSystem
),使用 FSSpecHandler
。您也可以手動執行此操作以取得具有 PyArrow FileSystem 介面的物件
from pyarrow.fs import PyFileSystem, FSSpecHandler
pa_fs = PyFileSystem(FSSpecHandler(fs))
然後,FileSystem
的所有功能都可存取
# write data
with pa_fs.open_output_stream('mycontainer/pyarrowtest.dat') as stream:
stream.write(b'data')
# read data
with pa_fs.open_input_stream('mycontainer/pyarrowtest.dat') as stream:
print(stream.readall())
#b'data'
# read a partitioned dataset
ds.dataset("data/", filesystem=pa_fs)
將 Arrow 檔案系統與 fsspec 搭配使用#
Arrow FileSystem 介面具有有限且面向開發人員的 API 介面。這對於基本互動以及與 Arrow 的 IO 功能一起使用已足夠。另一方面,fsspec 介面提供了非常大的 API,其中包含許多輔助方法。如果您想使用這些方法,或者如果您需要與期望與 fsspec 相容的檔案系統物件的套件互動,則可以使用 fsspec 包裝 Arrow FileSystem 物件。
從 fsspec
版本 2021.09 開始,ArrowFSWrapper
可以用於此目的
>>> from pyarrow import fs
>>> local = fs.LocalFileSystem()
>>> from fsspec.implementations.arrow import ArrowFSWrapper
>>> local_fsspec = ArrowFSWrapper(local)
產生的物件現在具有與 fsspec 相容的介面,同時在底層由 Arrow FileSystem 支援。建立目錄和檔案以及列出內容的使用範例
>>> local_fsspec.mkdir("./test")
>>> local_fsspec.touch("./test/file.txt")
>>> local_fsspec.ls("./test/")
['./test/file.txt']
如需更多資訊,請參閱 fsspec 文件。