Skip to content

Commit 02fd984

Browse files
committed
closes #23283
1 parent caea25a commit 02fd984

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ Other Enhancements
213213
- New attribute :attr:`__git_version__` will return git commit sha of current build (:issue:`21295`).
214214
- Compatibility with Matplotlib 3.0 (:issue:`22790`).
215215
- Added :meth:`Interval.overlaps`, :meth:`IntervalArray.overlaps`, and :meth:`IntervalIndex.overlaps` for determining overlaps between interval-like objects (:issue:`21998`)
216+
- :func:`~DataFrame.to_parquet` now supports writing a DataFrame as a directory of parquet files partitioned by a subset of the columns. (:issue:`23283`).
216217
- :meth:`Timestamp.tz_localize`, :meth:`DatetimeIndex.tz_localize`, and :meth:`Series.tz_localize` have gained the ``nonexistent`` argument for alternative handling of nonexistent times. See :ref:`timeseries.timezone_nonexsistent` (:issue:`8917`)
217218

218219
.. _whatsnew_0240.api_breaking:

pandas/io/parquet.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,18 @@ def write(self, df, path, compression='snappy',
121121
table = self.api.Table.from_pandas(df, timestamps_to_ms=True,
122122
**from_pandas_kwargs)
123123
self.api.parquet.write_table(
124-
table, path, compression=compression, **kwargs)
124+
table, path, compression=compression, **kwargs)
125125

126126
else:
127127
table = self.api.Table.from_pandas(df, **from_pandas_kwargs)
128-
self.api.parquet.write_table(
129-
table, path, compression=compression,
130-
coerce_timestamps=coerce_timestamps, **kwargs)
128+
if 'partition_cols' in kwargs:
129+
self.api.parquet.write_to_dataset(
130+
table, path, compression=compression,
131+
coerce_timestamps=coerce_timestamps, **kwargs)
132+
else:
133+
self.api.parquet.write_table(
134+
table, path, compression=compression,
135+
coerce_timestamps=coerce_timestamps, **kwargs)
131136

132137
def read(self, path, columns=None, **kwargs):
133138
path, _, _, should_close = get_filepath_or_buffer(path)
@@ -252,7 +257,8 @@ def to_parquet(df, path, engine='auto', compression='snappy', index=None,
252257
----------
253258
df : DataFrame
254259
path : string
255-
File path
260+
File path ( Will be used as `root_path` if
261+
`partition_cols` is provided as parameter for 'pyarrow' engine).
256262
engine : {'auto', 'pyarrow', 'fastparquet'}, default 'auto'
257263
Parquet library to use. If 'auto', then the option
258264
``io.parquet.engine`` is used. The default ``io.parquet.engine``

pandas/tests/io/test_parquet.py

+20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
""" test parquet compat """
22

33
import pytest
4+
import tempfile
5+
import shutil
46
import datetime
57
from distutils.version import LooseVersion
68
from warnings import catch_warnings
@@ -478,6 +480,24 @@ def test_s3_roundtrip(self, df_compat, s3_resource, pa):
478480
check_round_trip(df_compat, pa,
479481
path='s3://pandas-test/pyarrow.parquet')
480482

483+
def test_partition_cols_supported(self, pa_ge_070, df_full):
484+
partition_cols = ['bool', 'int']
485+
df = df_full
486+
path = tempfile.mkdtemp()
487+
df.to_parquet(path, partition_cols=partition_cols,
488+
compression=None)
489+
import pyarrow.parquet as pq
490+
dataset = pq.ParquetDataset(path, validate_schema=False)
491+
assert len(dataset.pieces) == 2
492+
assert len(dataset.partitions.partition_names) == 2
493+
assert dataset.partitions.partition_names == set(partition_cols)
494+
shutil.rmtree(path)
495+
496+
def test_ignore_partition_cols_lt_070(self, pa_lt_070, df_full):
497+
partition_cols = ['bool', 'int']
498+
pa = pa_lt_070
499+
df = df_full
500+
check_round_trip(df, pa, write_kwargs={'partition_cols': partition_cols})
481501

482502
class TestParquetFastParquet(Base):
483503

0 commit comments

Comments
 (0)