Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v2.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ enhancement2
Other enhancements
^^^^^^^^^^^^^^^^^^
- Improve error message when setting :class:`DataFrame` with wrong number of columns through :meth:`DataFrame.isetitem` (:issue:`51701`)
-
- Let :meth:`DataFrame.to_feather` accept a non-default :class:`Index` and non-string column names (:issue:`51787`)

.. ---------------------------------------------------------------------------
.. _whatsnew_210.notable_bug_fixes:
Expand Down
38 changes: 1 addition & 37 deletions pandas/io/feather_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@
arrays,
get_option,
)
from pandas.core.api import (
DataFrame,
RangeIndex,
)
from pandas.core.api import DataFrame
from pandas.core.shared_docs import _shared_docs

from pandas.io.common import get_handle
Expand Down Expand Up @@ -60,39 +57,6 @@ def to_feather(
if not isinstance(df, DataFrame):
raise ValueError("feather only support IO with DataFrames")

valid_types = {"string", "unicode"}

# validate index
# --------------

# validate that we have only a default index
# raise on anything else as we don't serialize the index

if not df.index.dtype == "int64":
typ = type(df.index)
raise ValueError(
f"feather does not support serializing {typ} "
"for the index; you can .reset_index() to make the index into column(s)"
)

if not df.index.equals(RangeIndex.from_range(range(len(df)))):
raise ValueError(
"feather does not support serializing a non-default index for the index; "
"you can .reset_index() to make the index into column(s)"
)

if df.index.name is not None:
raise ValueError(
"feather does not serialize index meta-data on a default index"
)

# validate columns
# ----------------

# must have value column names (strings only)
if df.columns.inferred_type not in valid_types:
raise ValueError("feather must have string column names")

with get_handle(
path, "wb", storage_options=storage_options, is_text=False
) as handles:
Expand Down
42 changes: 5 additions & 37 deletions pandas/tests/io/test_feather.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def check_external_error_on_write(self, df):

def check_round_trip(self, df, expected=None, write_kwargs={}, **read_kwargs):
if expected is None:
expected = df
expected = df.copy()

with tm.ensure_clean() as path:
to_feather(df, path, **write_kwargs)
Expand Down Expand Up @@ -94,11 +94,6 @@ def test_duplicate_columns(self):
df = pd.DataFrame(np.arange(12).reshape(4, 3), columns=list("aaa")).copy()
self.check_external_error_on_write(df)

def test_stringify_columns(self):
df = pd.DataFrame(np.arange(12).reshape(4, 3)).copy()
msg = "feather must have string column names"
self.check_error_on_write(df, ValueError, msg)

def test_read_columns(self):
# GH 24025
df = pd.DataFrame(
Expand Down Expand Up @@ -128,37 +123,6 @@ def test_rw_use_threads(self):
self.check_round_trip(df, use_threads=True)
self.check_round_trip(df, use_threads=False)

def test_write_with_index(self):
df = pd.DataFrame({"A": [1, 2, 3]})
self.check_round_trip(df)

msg = (
r"feather does not support serializing .* for the index; "
r"you can \.reset_index\(\) to make the index into column\(s\)"
)
# non-default index
for index in [
[2, 3, 4],
pd.date_range("20130101", periods=3),
list("abc"),
[1, 3, 4],
pd.MultiIndex.from_tuples([("a", 1), ("a", 2), ("b", 1)]),
]:
df.index = index
self.check_error_on_write(df, ValueError, msg)

# index with meta-data
df.index = [0, 1, 2]
df.index.name = "foo"
msg = "feather does not serialize index meta-data on a default index"
self.check_error_on_write(df, ValueError, msg)

# column multi-index
df.index = [0, 1, 2]
df.columns = pd.MultiIndex.from_tuples([("a", 1)])
msg = "feather must have string column names"
self.check_error_on_write(df, ValueError, msg)

def test_path_pathlib(self):
df = tm.makeDataFrame().reset_index()
result = tm.round_trip_pathlib(df.to_feather, read_feather)
Expand Down Expand Up @@ -250,3 +214,7 @@ def test_read_json_nullable(self, string_storage, dtype_backend, option):
)

tm.assert_frame_equal(result, expected)

def test_int_columns_and_index(self):
df = pd.DataFrame({"a": [1, 2, 3]}, index=pd.Index([3, 4, 5], name="test"))
self.check_round_trip(df)