Skip to content

DEPR: Deprecate from_csv in favor of read_csv #17812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 10, 2017
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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.21.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,7 @@ Other API Changes
Deprecations
~~~~~~~~~~~~

- :meth:`DataFrame.from_csv` and :meth:`Series.from_csv` have been deprecated in favor of :func:`read_csv()` (:issue:`4191`)
- :func:`read_excel()` has deprecated ``sheetname`` in favor of ``sheet_name`` for consistency with ``.to_excel()`` (:issue:`10559`).
- :func:`read_excel()` has deprecated ``parse_cols`` in favor of ``usecols`` for consistency with :func:`read_csv` (:issue:`4988`)
- :func:`read_csv()` has deprecated the ``tupleize_cols`` argument. Column tuples will always be converted to a ``MultiIndex`` (:issue:`17060`)
Expand Down
11 changes: 9 additions & 2 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def _constructor(self):

_constructor_sliced = Series
_deprecations = NDFrame._deprecations | frozenset(
['sortlevel', 'get_value', 'set_value'])
['sortlevel', 'get_value', 'set_value', 'from_csv'])

@property
def _constructor_expanddim(self):
Expand Down Expand Up @@ -1291,7 +1291,7 @@ def from_csv(cls, path, header=0, sep=',', index_col=0, parse_dates=True,
encoding=None, tupleize_cols=False,
infer_datetime_format=False):
"""
Read CSV file (DISCOURAGED, please use :func:`pandas.read_csv`
Read CSV file (DEPRECATED, please use :func:`pandas.read_csv`
instead).
It is preferable to use the more powerful :func:`pandas.read_csv`
Expand Down Expand Up @@ -1339,6 +1339,13 @@ def from_csv(cls, path, header=0, sep=',', index_col=0, parse_dates=True,
y : DataFrame
"""

warnings.warn("from_csv is deprecated. Please use read_csv(...) "
"instead. Note that some of the default arguments are "
"different, so please refer to the documentation "
"for from_csv when changing your function calls",
FutureWarning, stacklevel=2)

from pandas.io.parsers import read_table
return read_table(path, header=header, sep=sep,
parse_dates=parse_dates, index_col=index_col,
Expand Down
7 changes: 5 additions & 2 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class Series(base.IndexOpsMixin, generic.NDFrame):
_metadata = ['name']
_accessors = frozenset(['dt', 'cat', 'str'])
_deprecations = generic.NDFrame._deprecations | frozenset(
['sortlevel', 'reshape', 'get_value', 'set_value'])
['sortlevel', 'reshape', 'get_value', 'set_value', 'from_csv'])
_allow_index_ops = True

def __init__(self, data=None, index=None, dtype=None, name=None,
Expand Down Expand Up @@ -2688,7 +2688,7 @@ def between(self, left, right, inclusive=True):
def from_csv(cls, path, sep=',', parse_dates=True, header=None,
index_col=0, encoding=None, infer_datetime_format=False):
"""
Read CSV file (DISCOURAGED, please use :func:`pandas.read_csv`
Read CSV file (DEPRECATED, please use :func:`pandas.read_csv`
instead).

It is preferable to use the more powerful :func:`pandas.read_csv`
Expand Down Expand Up @@ -2736,6 +2736,9 @@ def from_csv(cls, path, sep=',', parse_dates=True, header=None,
-------
y : Series
"""

# We're calling `DataFrame.from_csv` in the implementation,
# which will propagate a warning regarding `from_csv` deprecation.
from pandas.core.frame import DataFrame
df = DataFrame.from_csv(path, header=header, index_col=index_col,
sep=sep, parse_dates=parse_dates,
Expand Down
83 changes: 53 additions & 30 deletions pandas/tests/frame/test_to_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@

class TestDataFrameToCSV(TestData):

def read_csv(self, path, **kwargs):
params = dict(index_col=0, parse_dates=True)
params.update(**kwargs)

return pd.read_csv(path, **params)

def test_from_csv_deprecation(self):
# see gh-17812
with ensure_clean('__tmp_from_csv_deprecation__') as path:
self.tsframe.to_csv(path)

with tm.assert_produces_warning(FutureWarning):
depr_recons = DataFrame.from_csv(path)
assert_frame_equal(self.tsframe, depr_recons)

def test_to_csv_from_csv1(self):

with ensure_clean('__tmp_to_csv_from_csv1__') as path:
Expand All @@ -43,24 +58,25 @@ def test_to_csv_from_csv1(self):

# test roundtrip
self.tsframe.to_csv(path)
recons = DataFrame.from_csv(path)

recons = self.read_csv(path)
assert_frame_equal(self.tsframe, recons)

self.tsframe.to_csv(path, index_label='index')
recons = DataFrame.from_csv(path, index_col=None)
recons = self.read_csv(path, index_col=None)

assert(len(recons.columns) == len(self.tsframe.columns) + 1)

# no index
self.tsframe.to_csv(path, index=False)
recons = DataFrame.from_csv(path, index_col=None)
recons = self.read_csv(path, index_col=None)
assert_almost_equal(self.tsframe.values, recons.values)

# corner case
dm = DataFrame({'s1': Series(lrange(3), lrange(3)),
's2': Series(lrange(2), lrange(2))})
dm.to_csv(path)
recons = DataFrame.from_csv(path)

recons = self.read_csv(path)
assert_frame_equal(dm, recons)

def test_to_csv_from_csv2(self):
Expand All @@ -71,27 +87,26 @@ def test_to_csv_from_csv2(self):
df = DataFrame(np.random.randn(3, 3), index=['a', 'a', 'b'],
columns=['x', 'y', 'z'])
df.to_csv(path)
result = DataFrame.from_csv(path)
result = self.read_csv(path)
assert_frame_equal(result, df)

midx = MultiIndex.from_tuples(
[('A', 1, 2), ('A', 1, 2), ('B', 1, 2)])
df = DataFrame(np.random.randn(3, 3), index=midx,
columns=['x', 'y', 'z'])

df.to_csv(path)
result = DataFrame.from_csv(path, index_col=[0, 1, 2],
parse_dates=False)
# TODO from_csv names index ['Unnamed: 1', 'Unnamed: 2'] should it
# ?
result = self.read_csv(path, index_col=[0, 1, 2],
parse_dates=False)
assert_frame_equal(result, df, check_names=False)

# column aliases
col_aliases = Index(['AA', 'X', 'Y', 'Z'])
self.frame2.to_csv(path, header=col_aliases)
rs = DataFrame.from_csv(path)

rs = self.read_csv(path)
xp = self.frame2.copy()
xp.columns = col_aliases

assert_frame_equal(xp, rs)

pytest.raises(ValueError, self.frame2.to_csv, path,
Expand Down Expand Up @@ -231,8 +246,9 @@ def make_dtnat_arr(n, nnat=None):
with ensure_clean('1.csv') as pth:
df = DataFrame(dict(a=s1, b=s2))
df.to_csv(pth, chunksize=chunksize)
recons = DataFrame.from_csv(pth)._convert(datetime=True,
coerce=True)

recons = self.read_csv(pth)._convert(datetime=True,
coerce=True)
assert_frame_equal(df, recons, check_names=False,
check_less_precise=True)

Expand All @@ -247,16 +263,17 @@ def _do_test(df, r_dtype=None, c_dtype=None,
if rnlvl is not None:
kwargs['index_col'] = lrange(rnlvl)
kwargs['header'] = lrange(cnlvl)

with ensure_clean('__tmp_to_csv_moar__') as path:
df.to_csv(path, encoding='utf8',
chunksize=chunksize, tupleize_cols=False)
recons = DataFrame.from_csv(
path, tupleize_cols=False, **kwargs)
recons = self.read_csv(path, tupleize_cols=False, **kwargs)
else:
kwargs['header'] = 0

with ensure_clean('__tmp_to_csv_moar__') as path:
df.to_csv(path, encoding='utf8', chunksize=chunksize)
recons = DataFrame.from_csv(path, **kwargs)
recons = self.read_csv(path, **kwargs)

def _to_uni(x):
if not isinstance(x, compat.text_type):
Expand Down Expand Up @@ -398,7 +415,7 @@ def test_to_csv_from_csv_w_some_infs(self):

with ensure_clean() as path:
self.frame.to_csv(path)
recons = DataFrame.from_csv(path)
recons = self.read_csv(path)

# TODO to_csv drops column name
assert_frame_equal(self.frame, recons, check_names=False)
Expand All @@ -413,7 +430,7 @@ def test_to_csv_from_csv_w_all_infs(self):

with ensure_clean() as path:
self.frame.to_csv(path)
recons = DataFrame.from_csv(path)
recons = self.read_csv(path)

# TODO to_csv drops column name
assert_frame_equal(self.frame, recons, check_names=False)
Expand Down Expand Up @@ -448,11 +465,13 @@ def test_to_csv_headers(self):
to_df = DataFrame([[1, 2], [3, 4]], columns=['X', 'Y'])
with ensure_clean('__tmp_to_csv_headers__') as path:
from_df.to_csv(path, header=['X', 'Y'])
recons = DataFrame.from_csv(path)
recons = self.read_csv(path)

assert_frame_equal(to_df, recons)

from_df.to_csv(path, index=False, header=['X', 'Y'])
recons = DataFrame.from_csv(path)
recons = self.read_csv(path)

recons.reset_index(inplace=True)
assert_frame_equal(to_df, recons)

Expand All @@ -471,13 +490,15 @@ def test_to_csv_multiindex(self):

# round trip
frame.to_csv(path)
df = DataFrame.from_csv(path, index_col=[0, 1], parse_dates=False)

df = self.read_csv(path, index_col=[0, 1],
parse_dates=False)

# TODO to_csv drops column name
assert_frame_equal(frame, df, check_names=False)
assert frame.index.names == df.index.names

# needed if setUP becomes a classmethod
# needed if setUp becomes a class method
self.frame.index = old_index

# try multiindex with dates
Expand All @@ -487,21 +508,22 @@ def test_to_csv_multiindex(self):
tsframe.index = MultiIndex.from_arrays(new_index)

tsframe.to_csv(path, index_label=['time', 'foo'])
recons = DataFrame.from_csv(path, index_col=[0, 1])
recons = self.read_csv(path, index_col=[0, 1])

# TODO to_csv drops column name
assert_frame_equal(tsframe, recons, check_names=False)

# do not load index
tsframe.to_csv(path)
recons = DataFrame.from_csv(path, index_col=None)
recons = self.read_csv(path, index_col=None)
assert len(recons.columns) == len(tsframe.columns) + 2

# no index
tsframe.to_csv(path, index=False)
recons = DataFrame.from_csv(path, index_col=None)
recons = self.read_csv(path, index_col=None)
assert_almost_equal(recons.values, self.tsframe.values)

# needed if setUP becomes classmethod
# needed if setUp becomes class method
self.tsframe.index = old_index

with ensure_clean('__tmp_to_csv_multiindex__') as path:
Expand Down Expand Up @@ -606,7 +628,8 @@ def _make_frame(names=None):
with ensure_clean('__tmp_to_csv_multiindex__') as path:
# empty
tsframe[:0].to_csv(path)
recons = DataFrame.from_csv(path)
recons = self.read_csv(path)

exp = tsframe[:0]
exp.index = []

Expand All @@ -631,7 +654,7 @@ def test_to_csv_withcommas(self):

with ensure_clean('__tmp_to_csv_withcommas__.csv') as path:
df.to_csv(path)
df2 = DataFrame.from_csv(path)
df2 = self.read_csv(path)
assert_frame_equal(df2, df)

def test_to_csv_mixed(self):
Expand Down Expand Up @@ -746,7 +769,7 @@ def test_to_csv_wide_frame_formatting(self):

def test_to_csv_bug(self):
f1 = StringIO('a,1.0\nb,2.0')
df = DataFrame.from_csv(f1, header=None)
df = self.read_csv(f1, header=None)
newdf = DataFrame({'t': df[df.columns[0]]})

with ensure_clean() as path:
Expand Down
Loading