pip install pyarrow★One wheel — Parquet, compute, datasets included.import pyarrow as pa★Core: arrays, tables, types, schema.import pyarrow.compute as pc★Kernels: filter, aggregate, arithmetic.import pyarrow.parquet as pq★Read/write Parquet files.import pyarrow.dataset as dsMulti-file, larger-than-memory datasets.import pyarrow.csv, pyarrow.featherAlsopyarrow.json,pyarrow.fs.pa.__version__Tracks Apache Arrow, e.g.'25.0.1'.
pa.Array★One column, one contiguous chunk (+ null bitmap).pa.ChunkedArrayOne column split across several arrays.pa.RecordBatchArrays + Schema — one contiguous slice.pa.Table★ChunkedArrays + Schema — the everyday object.pa.Schema / Field / DataTypeColumn names + types + metadata.
pa.array([1, 2, None])★Type inferred; nulls allowed.pa.array([1, 2], type=pa.int32())Force an explicit type.pa.table({"n": [1,2], "s": ["a","b"]})★Dict of columns → Table (most common).pa.Table.from_arrays([a, b], names=[...])Build from existing arrays.pa.chunked_array([[1,2],[3,4]])Glue chunks into one logical column.pa.record_batch({...})Contiguous batch (streaming unit).
pa.int64() # float64 · bool_ · string★Primitive type objects.pa.timestamp("ms") # date32 · decimal128Temporal & fixed-precision types.pa.list_(pa.int32())Nested list; alsopa.struct([...]).pa.dictionary(pa.int32(), pa.string())Dictionary-encoded (like pandas category).pa.schema([("n", pa.int64())])★Names + types;pa.field(...)for metadata.table.cast(schema)Cast a whole table to a new schema.
table.schema★Column names, types, metadata.table.num_rows # .num_columnsShape of the table.table["col"] # → ChunkedArray★Select one column.table.select(["a", "b"])★Project a subset of columns.table.slice(0, 5)Zero-copy row slice.table.rename_columns([...])Alsodrop_columns,append_column.table.combine_chunks()Flatten chunks into contiguous arrays.
pc.field("x") > 5★Build a filter expression.table.filter(expr)★Keep rows where the expression is true.(pc.field("a")>0) & (pc.field("b")<9)Combine with&|~.pc.field("c").isin(["IN","US"])★Membership test.table.take([0, 3, 7])Pick rows by index.arr.filter(mask)Filter an array by a boolean mask.
table.group_by("k").aggregate([("v","sum")])★Split-apply-combine, in Arrow..aggregate([("v","sum"),("v","mean")])Several aggregations at once..aggregate([([], "count_all")])Rows per group.pc.sum(col) # mean · min_max · stddev★Whole-column reductions.table.sort_by("x")★[("x","descending")]for order.pc.value_counts(col) # uniqueFrequency table / distinct values.
pc.add(col, 1) # multiply · subtractVectorized arithmetic.pc.cast(col, pa.int32())★Change a column's type.pc.fill_null(col, 0)★Replace nulls with a value.pc.dictionary_encode(col)Compress low-cardinality strings.pc.utf8_upper(col) # match_substringString kernels.pc.is_null(col) # is_validNull-checking masks.
left.join(right, keys="id")★Default is a left-outer join.join_type="inner"Also"left outer","full outer".join_type="left semi"Rows in left that have a match.join_type="left anti"Rows in left with no match.left_suffix="_l", right_suffix="_r"Disambiguate colliding names.
pq.read_table("data.parquet")★File → Arrow Table.pq.read_table(p, columns=[...], filters=[...])★Column + row pushdown — reads less.pq.write_table(table, p, compression="zstd")★snappy(default) ·zstd·gzip.pq.write_to_dataset(table, root, partition_cols=[...])Write a Hive-partitioned tree.pq.ParquetFile(p).schema_arrowPeek schema without reading data.pq.read_metadata(p)Row counts, row groups, stats.
pa.csv.read_csv("f.csv")★Fast multithreaded CSV → Table.pa.csv.write_csv(table, "f.csv")Table → CSV.pa.json.read_json("f.json")Line-delimited JSON → Table.pa.feather.write_feather(table, "f.arrow")★Fastest round-trip;read_featherback.pa.ipc.new_stream(sink, schema)Stream RecordBatches (Feather = IPC on disk).
ds.dataset("dir/", format="parquet")★Many files as one logical table.dataset.to_table()Materialize the whole thing (careful).dataset.scanner(columns=c, filter=e).to_table()★Pushdown — prune files/rows before reading.dataset.filter(pc.field("x")>5)Lazy filter; also.head(5).ds.write_dataset(table, base, partitioning=...)Write a partitioned dataset.
ds.dataset("s3://bucket/path/")★URI → filesystem is inferred.pa.fs.S3FileSystem(region="us-east-1")Explicit S3 handle.pa.fs.GcsFileSystem() # LocalFileSystemGCS, local, and more.pa.fs.HadoopFileSystem(host, port)HDFS access.filesystem=fsPass to any read/write call.
pa.Table.from_pandas(df)★pandas DataFrame → Arrow Table.table.to_pandas()★Arrow Table → pandas DataFrame.table.to_pandas(types_mapper=pd.ArrowDtype)★arrow-backedStay Arrow-backed — avoids object dtype.arr.to_numpy(zero_copy_only=True)no copyShare buffers with NumPy where possible.pa.array(np_arr)NumPy → Arrow (zero-copy for numerics).pl.from_arrow(table)Polars & DuckDB read Arrow natively.
table["x"][0] = 9immutableArrow is read-only — build a new object instead.to_pandas() # object dtypecopiesCopies strings — usetypes_mapper=pd.ArrowDtype.chunked.to_numpy(zero_copy_only=True)failsMultiple chunks aren't contiguous —combine_chunks().df.to_parquet() # whole fileno pushdownUseds.scannerto filter before reading.pa.Tablenot in specA PyArrow convenience — RecordBatch is the wire unit.