Skip to content

Commit deee0f3

Browse files
committed
DEPR: Deprecate from_csv in favor of read_csv
Closes gh-4191.
1 parent f9ba6fe commit deee0f3

File tree

5 files changed

+103
-55
lines changed

5 files changed

+103
-55
lines changed

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ Other API Changes
714714
Deprecations
715715
~~~~~~~~~~~~
716716

717+
- :meth:`DataFrame.from_csv` and :meth:`Series.from_csv` have been deprecated in favor of :func:`read_csv()` (:issue:`4191`)
717718
- :func:`read_excel()` has deprecated ``sheetname`` in favor of ``sheet_name`` for consistency with ``.to_excel()`` (:issue:`10559`).
718719
- :func:`read_excel()` has deprecated ``parse_cols`` in favor of ``usecols`` for consistency with :func:`read_csv` (:issue:`4988`)
719720
- The ``convert`` parameter has been deprecated in the ``.take()`` method, as it was not being respected (:issue:`16948`)

pandas/core/frame.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ def from_csv(cls, path, header=0, sep=',', index_col=0, parse_dates=True,
12911291
encoding=None, tupleize_cols=False,
12921292
infer_datetime_format=False):
12931293
"""
1294-
Read CSV file (DISCOURAGED, please use :func:`pandas.read_csv`
1294+
Read CSV file (DEPRECATED, please use :func:`pandas.read_csv`
12951295
instead).
12961296
12971297
It is preferable to use the more powerful :func:`pandas.read_csv`
@@ -1339,6 +1339,13 @@ def from_csv(cls, path, header=0, sep=',', index_col=0, parse_dates=True,
13391339
y : DataFrame
13401340
13411341
"""
1342+
1343+
warnings.warn("from_csv is deprecated. Please use read_csv(...) "
1344+
"instead. Note that some of the default arguments are "
1345+
"different, so please refer to the documentation "
1346+
"for from_csv when changing your function calls",
1347+
FutureWarning, stacklevel=2)
1348+
13421349
from pandas.io.parsers import read_table
13431350
return read_table(path, header=header, sep=sep,
13441351
parse_dates=parse_dates, index_col=index_col,

pandas/core/series.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -2688,7 +2688,7 @@ def between(self, left, right, inclusive=True):
26882688
def from_csv(cls, path, sep=',', parse_dates=True, header=None,
26892689
index_col=0, encoding=None, infer_datetime_format=False):
26902690
"""
2691-
Read CSV file (DISCOURAGED, please use :func:`pandas.read_csv`
2691+
Read CSV file (DEPRECATED, please use :func:`pandas.read_csv`
26922692
instead).
26932693
26942694
It is preferable to use the more powerful :func:`pandas.read_csv`
@@ -2736,6 +2736,9 @@ def from_csv(cls, path, sep=',', parse_dates=True, header=None,
27362736
-------
27372737
y : Series
27382738
"""
2739+
2740+
# We're calling `DataFrame.from_csv` in the implementation,
2741+
# which will propagate a warning regarding `from_csv` deprecation.
27392742
from pandas.core.frame import DataFrame
27402743
df = DataFrame.from_csv(path, header=header, index_col=index_col,
27412744
sep=sep, parse_dates=parse_dates,

pandas/tests/frame/test_to_csv.py

+49-30
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131

3232
class TestDataFrameToCSV(TestData):
3333

34+
def read_csv(self, path, **kwargs):
35+
params = dict(index_col=0, parse_dates=True)
36+
params.update(**kwargs)
37+
38+
return pd.read_csv(path, **params)
39+
3440
def test_to_csv_from_csv1(self):
3541

3642
with ensure_clean('__tmp_to_csv_from_csv1__') as path:
@@ -43,24 +49,30 @@ def test_to_csv_from_csv1(self):
4349

4450
# test roundtrip
4551
self.tsframe.to_csv(path)
46-
recons = DataFrame.from_csv(path)
47-
52+
recons = self.read_csv(path)
4853
assert_frame_equal(self.tsframe, recons)
4954

55+
with tm.assert_produces_warning(FutureWarning,
56+
check_stacklevel=False):
57+
depr_recons = DataFrame.from_csv(path)
58+
assert_frame_equal(self.tsframe, depr_recons)
59+
5060
self.tsframe.to_csv(path, index_label='index')
51-
recons = DataFrame.from_csv(path, index_col=None)
61+
recons = self.read_csv(path, index_col=None)
62+
5263
assert(len(recons.columns) == len(self.tsframe.columns) + 1)
5364

5465
# no index
5566
self.tsframe.to_csv(path, index=False)
56-
recons = DataFrame.from_csv(path, index_col=None)
67+
recons = self.read_csv(path, index_col=None)
5768
assert_almost_equal(self.tsframe.values, recons.values)
5869

5970
# corner case
6071
dm = DataFrame({'s1': Series(lrange(3), lrange(3)),
6172
's2': Series(lrange(2), lrange(2))})
6273
dm.to_csv(path)
63-
recons = DataFrame.from_csv(path)
74+
75+
recons = self.read_csv(path)
6476
assert_frame_equal(dm, recons)
6577

6678
def test_to_csv_from_csv2(self):
@@ -71,27 +83,26 @@ def test_to_csv_from_csv2(self):
7183
df = DataFrame(np.random.randn(3, 3), index=['a', 'a', 'b'],
7284
columns=['x', 'y', 'z'])
7385
df.to_csv(path)
74-
result = DataFrame.from_csv(path)
86+
result = self.read_csv(path)
7587
assert_frame_equal(result, df)
7688

7789
midx = MultiIndex.from_tuples(
7890
[('A', 1, 2), ('A', 1, 2), ('B', 1, 2)])
7991
df = DataFrame(np.random.randn(3, 3), index=midx,
8092
columns=['x', 'y', 'z'])
93+
8194
df.to_csv(path)
82-
result = DataFrame.from_csv(path, index_col=[0, 1, 2],
83-
parse_dates=False)
84-
# TODO from_csv names index ['Unnamed: 1', 'Unnamed: 2'] should it
85-
# ?
95+
result = self.read_csv(path, index_col=[0, 1, 2],
96+
parse_dates=False)
8697
assert_frame_equal(result, df, check_names=False)
8798

8899
# column aliases
89100
col_aliases = Index(['AA', 'X', 'Y', 'Z'])
90101
self.frame2.to_csv(path, header=col_aliases)
91-
rs = DataFrame.from_csv(path)
102+
103+
rs = self.read_csv(path)
92104
xp = self.frame2.copy()
93105
xp.columns = col_aliases
94-
95106
assert_frame_equal(xp, rs)
96107

97108
pytest.raises(ValueError, self.frame2.to_csv, path,
@@ -231,8 +242,9 @@ def make_dtnat_arr(n, nnat=None):
231242
with ensure_clean('1.csv') as pth:
232243
df = DataFrame(dict(a=s1, b=s2))
233244
df.to_csv(pth, chunksize=chunksize)
234-
recons = DataFrame.from_csv(pth)._convert(datetime=True,
235-
coerce=True)
245+
246+
recons = self.read_csv(pth)._convert(datetime=True,
247+
coerce=True)
236248
assert_frame_equal(df, recons, check_names=False,
237249
check_less_precise=True)
238250

@@ -247,16 +259,17 @@ def _do_test(df, r_dtype=None, c_dtype=None,
247259
if rnlvl is not None:
248260
kwargs['index_col'] = lrange(rnlvl)
249261
kwargs['header'] = lrange(cnlvl)
262+
250263
with ensure_clean('__tmp_to_csv_moar__') as path:
251264
df.to_csv(path, encoding='utf8',
252265
chunksize=chunksize, tupleize_cols=False)
253-
recons = DataFrame.from_csv(
254-
path, tupleize_cols=False, **kwargs)
266+
recons = self.read_csv(path, tupleize_cols=False, **kwargs)
255267
else:
256268
kwargs['header'] = 0
269+
257270
with ensure_clean('__tmp_to_csv_moar__') as path:
258271
df.to_csv(path, encoding='utf8', chunksize=chunksize)
259-
recons = DataFrame.from_csv(path, **kwargs)
272+
recons = self.read_csv(path, **kwargs)
260273

261274
def _to_uni(x):
262275
if not isinstance(x, compat.text_type):
@@ -398,7 +411,7 @@ def test_to_csv_from_csv_w_some_infs(self):
398411

399412
with ensure_clean() as path:
400413
self.frame.to_csv(path)
401-
recons = DataFrame.from_csv(path)
414+
recons = self.read_csv(path)
402415

403416
# TODO to_csv drops column name
404417
assert_frame_equal(self.frame, recons, check_names=False)
@@ -413,7 +426,7 @@ def test_to_csv_from_csv_w_all_infs(self):
413426

414427
with ensure_clean() as path:
415428
self.frame.to_csv(path)
416-
recons = DataFrame.from_csv(path)
429+
recons = self.read_csv(path)
417430

418431
# TODO to_csv drops column name
419432
assert_frame_equal(self.frame, recons, check_names=False)
@@ -448,11 +461,13 @@ def test_to_csv_headers(self):
448461
to_df = DataFrame([[1, 2], [3, 4]], columns=['X', 'Y'])
449462
with ensure_clean('__tmp_to_csv_headers__') as path:
450463
from_df.to_csv(path, header=['X', 'Y'])
451-
recons = DataFrame.from_csv(path)
464+
recons = self.read_csv(path)
465+
452466
assert_frame_equal(to_df, recons)
453467

454468
from_df.to_csv(path, index=False, header=['X', 'Y'])
455-
recons = DataFrame.from_csv(path)
469+
recons = self.read_csv(path)
470+
456471
recons.reset_index(inplace=True)
457472
assert_frame_equal(to_df, recons)
458473

@@ -471,13 +486,15 @@ def test_to_csv_multiindex(self):
471486

472487
# round trip
473488
frame.to_csv(path)
474-
df = DataFrame.from_csv(path, index_col=[0, 1], parse_dates=False)
489+
490+
df = self.read_csv(path, index_col=[0, 1],
491+
parse_dates=False)
475492

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

480-
# needed if setUP becomes a classmethod
497+
# needed if setUp becomes a class method
481498
self.frame.index = old_index
482499

483500
# try multiindex with dates
@@ -487,21 +504,22 @@ def test_to_csv_multiindex(self):
487504
tsframe.index = MultiIndex.from_arrays(new_index)
488505

489506
tsframe.to_csv(path, index_label=['time', 'foo'])
490-
recons = DataFrame.from_csv(path, index_col=[0, 1])
507+
recons = self.read_csv(path, index_col=[0, 1])
508+
491509
# TODO to_csv drops column name
492510
assert_frame_equal(tsframe, recons, check_names=False)
493511

494512
# do not load index
495513
tsframe.to_csv(path)
496-
recons = DataFrame.from_csv(path, index_col=None)
514+
recons = self.read_csv(path, index_col=None)
497515
assert len(recons.columns) == len(tsframe.columns) + 2
498516

499517
# no index
500518
tsframe.to_csv(path, index=False)
501-
recons = DataFrame.from_csv(path, index_col=None)
519+
recons = self.read_csv(path, index_col=None)
502520
assert_almost_equal(recons.values, self.tsframe.values)
503521

504-
# needed if setUP becomes classmethod
522+
# needed if setUp becomes class method
505523
self.tsframe.index = old_index
506524

507525
with ensure_clean('__tmp_to_csv_multiindex__') as path:
@@ -599,7 +617,8 @@ def _make_frame(names=None):
599617
with ensure_clean('__tmp_to_csv_multiindex__') as path:
600618
# empty
601619
tsframe[:0].to_csv(path)
602-
recons = DataFrame.from_csv(path)
620+
recons = self.read_csv(path)
621+
603622
exp = tsframe[:0]
604623
exp.index = []
605624

@@ -624,7 +643,7 @@ def test_to_csv_withcommas(self):
624643

625644
with ensure_clean('__tmp_to_csv_withcommas__.csv') as path:
626645
df.to_csv(path)
627-
df2 = DataFrame.from_csv(path)
646+
df2 = self.read_csv(path)
628647
assert_frame_equal(df2, df)
629648

630649
def test_to_csv_mixed(self):
@@ -739,7 +758,7 @@ def test_to_csv_wide_frame_formatting(self):
739758

740759
def test_to_csv_bug(self):
741760
f1 = StringIO('a,1.0\nb,2.0')
742-
df = DataFrame.from_csv(f1, header=None)
761+
df = self.read_csv(f1, header=None)
743762
newdf = DataFrame({'t': df[df.columns[0]]})
744763

745764
with ensure_clean() as path:

pandas/tests/series/test_io.py

+41-23
Original file line numberDiff line numberDiff line change
@@ -20,43 +20,62 @@
2020

2121
class TestSeriesToCSV(TestData):
2222

23+
def read_csv(self, path, **kwargs):
24+
params = dict(squeeze=True, index_col=0,
25+
header=None, parse_dates=True)
26+
params.update(**kwargs)
27+
28+
header = params.get("header")
29+
out = pd.read_csv(path, **params)
30+
31+
if header is None:
32+
out.name = out.index.name = None
33+
34+
return out
35+
2336
def test_from_csv(self):
2437

2538
with ensure_clean() as path:
2639
self.ts.to_csv(path)
27-
ts = Series.from_csv(path)
40+
ts = self.read_csv(path)
2841
assert_series_equal(self.ts, ts, check_names=False)
42+
2943
assert ts.name is None
3044
assert ts.index.name is None
3145

32-
# GH10483
46+
with tm.assert_produces_warning(FutureWarning,
47+
check_stacklevel=False):
48+
depr_ts = Series.from_csv(path)
49+
assert_series_equal(depr_ts, ts)
50+
51+
# see gh-10483
3352
self.ts.to_csv(path, header=True)
34-
ts_h = Series.from_csv(path, header=0)
35-
assert ts_h.name == 'ts'
53+
ts_h = self.read_csv(path, header=0)
54+
assert ts_h.name == "ts"
3655

3756
self.series.to_csv(path)
38-
series = Series.from_csv(path)
39-
assert series.name is None
40-
assert series.index.name is None
57+
series = self.read_csv(path)
4158
assert_series_equal(self.series, series, check_names=False)
59+
4260
assert series.name is None
4361
assert series.index.name is None
4462

4563
self.series.to_csv(path, header=True)
46-
series_h = Series.from_csv(path, header=0)
47-
assert series_h.name == 'series'
64+
series_h = self.read_csv(path, header=0)
65+
assert series_h.name == "series"
4866

49-
outfile = open(path, 'w')
50-
outfile.write('1998-01-01|1.0\n1999-01-01|2.0')
67+
outfile = open(path, "w")
68+
outfile.write("1998-01-01|1.0\n1999-01-01|2.0")
5169
outfile.close()
52-
series = Series.from_csv(path, sep='|')
53-
checkseries = Series({datetime(1998, 1, 1): 1.0,
54-
datetime(1999, 1, 1): 2.0})
55-
assert_series_equal(checkseries, series)
5670

57-
series = Series.from_csv(path, sep='|', parse_dates=False)
58-
checkseries = Series({'1998-01-01': 1.0, '1999-01-01': 2.0})
59-
assert_series_equal(checkseries, series)
71+
series = self.read_csv(path, sep="|")
72+
check_series = Series({datetime(1998, 1, 1): 1.0,
73+
datetime(1999, 1, 1): 2.0})
74+
assert_series_equal(check_series, series)
75+
76+
series = self.read_csv(path, sep="|", parse_dates=False)
77+
check_series = Series({"1998-01-01": 1.0, "1999-01-01": 2.0})
78+
assert_series_equal(check_series, series)
6079

6180
def test_to_csv(self):
6281
import io
@@ -76,20 +95,19 @@ def test_to_csv_unicode_index(self):
7695
buf = StringIO()
7796
s = Series([u("\u05d0"), "d2"], index=[u("\u05d0"), u("\u05d1")])
7897

79-
s.to_csv(buf, encoding='UTF-8')
98+
s.to_csv(buf, encoding="UTF-8")
8099
buf.seek(0)
81100

82-
s2 = Series.from_csv(buf, index_col=0, encoding='UTF-8')
83-
101+
s2 = self.read_csv(buf, index_col=0, encoding="UTF-8")
84102
assert_series_equal(s, s2)
85103

86104
def test_to_csv_float_format(self):
87105

88106
with ensure_clean() as filename:
89107
ser = Series([0.123456, 0.234567, 0.567567])
90-
ser.to_csv(filename, float_format='%.2f')
108+
ser.to_csv(filename, float_format="%.2f")
91109

92-
rs = Series.from_csv(filename)
110+
rs = self.read_csv(filename)
93111
xp = Series([0.12, 0.23, 0.57])
94112
assert_series_equal(rs, xp)
95113

0 commit comments

Comments
 (0)