Skip to content

Commit e9d6678

Browse files
author
Kevin Sheppard
committed
CLN: PEP 8 improvements
1 parent 0727803 commit e9d6678

File tree

6 files changed

+75
-21
lines changed

6 files changed

+75
-21
lines changed

doc/source/basics.rst

+10-6
Original file line numberDiff line numberDiff line change
@@ -1524,13 +1524,15 @@ object conversion
15241524

15251525
.. note::
15261526

1527-
The syntax of :meth:`~DataFrame.convert_objects` changed in 0.17.0.
1527+
The syntax of :meth:`~DataFrame.convert_objects` changed in 0.17.0. See
1528+
:ref:`API changes <whatsnew_0170.api_breaking.convert_objects>`
1529+
for more details.
15281530

15291531
:meth:`~DataFrame.convert_objects` is a method to try to force conversion of
15301532
types from the ``object`` dtype to other types. To try converting specific
15311533
types that are *number like*, e.g. could be a string that represents a number,
1532-
pass ``numeric=True``. The force the conversion, add the keword argument
1533-
``coerce=True``. This will force strings and numbers alike to be numbers if
1534+
pass ``numeric=True``. To force the conversion, add the keyword argument
1535+
``coerce=True``. This will force strings and number-like objects to be numbers if
15341536
possible, otherwise they will be set to ``np.nan``.
15351537

15361538
.. ipython:: python
@@ -1559,10 +1561,12 @@ but occasionally has non-dates intermixed and you want to represent as missing.
15591561
s.convert_objects(datetime=True, coerce=True)
15601562
15611563
Without passing ``coerce=True``, :meth:`~DataFrame.convert_objects` will attempt
1562-
the *soft* conversion of any *object* dtypes, meaning that if all
1564+
*soft* conversion of any *object* dtypes, meaning that if all
15631565
the objects in a Series are of the same type, the Series will have that dtype.
1564-
Setting ``coerce=True`` will not *convert* - for example, a series of string
1565-
dates will not be converted to a series of datetimes.
1566+
Note that setting ``coerce=True`` does not *convert* arbitrary types to either
1567+
``datetime64[ns]`` or ``timedelta64[ns]``. For example, a series containing string
1568+
dates will not be converted to a series of datetimes. To convert between types,
1569+
see :ref:`converting to timestamps <timeseries.converting>`.
15661570

15671571
gotchas
15681572
~~~~~~~

doc/source/whatsnew/v0.17.0.txt

+30-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Backwards incompatible API changes
4848

4949
.. _whatsnew_0170.api_breaking.other:
5050

51+
.. _whatsnew_0170.api_breaking.convert_objects:
5152
Changes to convert_objects
5253
^^^^^^^^^^^^^^^^^^^^^^^^^^
5354
- ``DataFrame.convert_objects`` keyword arguments have been shortened. (:issue:`10265`)
@@ -66,7 +67,9 @@ keyword argument to ``'coerce'`` instead of ``True``, as in ``convert_dates='coe
6667

6768
.. ipython:: python
6869

69-
df = pd.DataFrame({'i': ['1','2'], 'f': ['apple', '4.2']})
70+
df = pd.DataFrame({'i': ['1','2'],
71+
'f': ['apple', '4.2'],
72+
's': ['apple','banana']})
7073
df
7174

7275
The old usage of ``DataFrame.convert_objects`` used `'coerce'` along with the
@@ -82,8 +85,32 @@ keyword argument to ``'coerce'`` instead of ``True``, as in ``convert_dates='coe
8285

8386
df.convert_objects(numeric=True, coerce=True)
8487

85-
- The new default behavior for ``DataFrame.convert_objects`` is to do nothing,
86-
and so it is necessary to pass at least one conversion target when calling.
88+
- In earlier versions of pandas, ``DataFrame.convert_objects`` would not coerce
89+
numeric types when there were no values convertible to a numeric type. For example,
90+
91+
.. code-block:: python
92+
93+
In [1]: df = pd.DataFrame({'s': ['a','b']})
94+
In [2]: df.convert_objects(convert_numeric='coerce')
95+
Out[2]:
96+
s
97+
0 a
98+
1 b
99+
100+
returns the original DataFrame with no conversion. This change alters
101+
this behavior so that
102+
103+
.. ipython:: python
104+
105+
pd.DataFrame({'s': ['a','b']})
106+
df.convert_objects(numeric=True, coerce=True)
107+
108+
converts all non-number-like strings to ``NaN``.
109+
110+
- In earlier versions of pandas, the default behavior was to try and convert
111+
datetimes and timestamps. The new default is for ``DataFrame.convert_objects``
112+
to do nothing, and so it is necessary to pass at least one conversion target
113+
in the method call.
87114

88115

89116
Other API Changes

pandas/core/common.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -1892,15 +1892,18 @@ def _possibly_convert_objects(values,
18921892
datetime=True,
18931893
numeric=True,
18941894
timedelta=True,
1895-
coerce=False):
1895+
coerce=False,
1896+
copy=True):
18961897
""" if we have an object dtype, try to coerce dates and/or numbers """
18971898

18981899
conversion_count = sum((datetime, numeric, timedelta))
18991900
if conversion_count == 0:
19001901
import warnings
1901-
warnings.warn('Must explicitly pass type for conversion. Original '
1902-
'value returned.', RuntimeWarning)
1903-
return values
1902+
warnings.warn('Must explicitly pass type for conversion. Defaulting to '
1903+
'pre-0.17 behavior where datetime=True, numeric=True, '
1904+
'timedelta=True and coerce=False', DeprecationWarning)
1905+
datetime = numeric = timedelta = True
1906+
coerce = False
19041907

19051908
if isinstance(values, (list, tuple)):
19061909
# List or scalar
@@ -1909,6 +1912,7 @@ def _possibly_convert_objects(values,
19091912
values = np.array([values], dtype=np.object_)
19101913
elif not is_object_dtype(values.dtype):
19111914
# If not object, do not attempt conversion
1915+
values = values.copy() if copy else values
19121916
return values
19131917

19141918
# If 1 flag is coerce, ensure 2 others are False
@@ -1942,6 +1946,7 @@ def _possibly_convert_objects(values,
19421946
coerce_numeric=True)
19431947
# If all NaNs, then do not-alter
19441948
values = converted if not isnull(converted).all() else values
1949+
values = values.copy() if copy else values
19451950
except:
19461951
pass
19471952

pandas/core/internals.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,8 @@ def convert(self, datetime=True, numeric=True, timedelta=True, coerce=False,
14761476
datetime=datetime,
14771477
numeric=numeric,
14781478
timedelta=timedelta,
1479-
coerce=coerce
1479+
coerce=coerce,
1480+
copy=copy
14801481
).reshape(values.shape)
14811482
values = _block_shape(values, ndim=self.ndim)
14821483
newb = make_block(values,
@@ -1490,7 +1491,8 @@ def convert(self, datetime=True, numeric=True, timedelta=True, coerce=False,
14901491
datetime=datetime,
14911492
numeric=numeric,
14921493
timedelta=timedelta,
1493-
coerce=coerce
1494+
coerce=coerce,
1495+
copy=copy
14941496
).reshape(self.values.shape)
14951497
blocks.append(make_block(values,
14961498
ndim=self.ndim, placement=self.mgr_locs))

pandas/tests/test_common.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import re
55

66
import nose
7-
from nose.tools import assert_equal
7+
from nose.tools import assert_equal, assert_true
88
import numpy as np
99
from pandas.tslib import iNaT, NaT
1010
from pandas import Series, DataFrame, date_range, DatetimeIndex, Timestamp, Float64Index
@@ -1026,6 +1026,22 @@ def test_dict_compat():
10261026
assert(com._dict_compat(expected) == expected)
10271027
assert(com._dict_compat(data_unchanged) == data_unchanged)
10281028

1029+
def test_possibly_convert_objects_copy():
1030+
values = np.array([1, 2])
1031+
1032+
out = com._possibly_convert_objects(values, copy=False)
1033+
assert_true(values is out)
1034+
1035+
out = com._possibly_convert_objects(values, copy=True)
1036+
assert_true(values is not out)
1037+
1038+
values = np.array(['apply','banana'])
1039+
out = com._possibly_convert_objects(values, copy=False)
1040+
assert_true(values is out)
1041+
1042+
out = com._possibly_convert_objects(values, copy=True)
1043+
assert_true(values is not out)
1044+
10291045

10301046
if __name__ == '__main__':
10311047
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],

pandas/tests/test_series.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -5959,23 +5959,23 @@ def test_convert_objects(self):
59595959

59605960
# test pass-through and non-conversion when other types selected
59615961
s = Series(['1.0','2.0','3.0'])
5962-
results = s.convert_objects(True,True,True)
5962+
results = s.convert_objects(datetime=True, numeric=True, timedelta=True)
59635963
expected = Series([1.0,2.0,3.0])
59645964
assert_series_equal(results, expected)
59655965
results = s.convert_objects(True,False,True)
59665966
assert_series_equal(results, s)
59675967

59685968
s = Series([datetime(2001, 1, 1, 0, 0),datetime(2001, 1, 1, 0, 0)],
59695969
dtype='O')
5970-
results = s.convert_objects(True,True,True)
5970+
results = s.convert_objects(datetime=True, numeric=True, timedelta=True)
59715971
expected = Series([datetime(2001, 1, 1, 0, 0),datetime(2001, 1, 1, 0, 0)])
59725972
assert_series_equal(results, expected)
5973-
results = s.convert_objects(False,True,True)
5973+
results = s.convert_objects(datetime=False,numeric=True,timedelta=True)
59745974
assert_series_equal(results, s)
59755975

59765976
td = datetime(2001, 1, 1, 0, 0) - datetime(2000, 1, 1, 0, 0)
59775977
s = Series([td, td], dtype='O')
5978-
results = s.convert_objects(True,True,True)
5978+
results = s.convert_objects(datetime=True, numeric=True, timedelta=True)
59795979
expected = Series([td, td])
59805980
assert_series_equal(results, expected)
59815981
results = s.convert_objects(True,True,False)
@@ -6068,7 +6068,7 @@ def test_convert_objects(self):
60686068
def test_convert_objects_no_arg_warning(self):
60696069
s = Series(['1.0','2'])
60706070
with warnings.catch_warnings(record=True) as w:
6071-
warnings.simplefilter('always', RuntimeWarning)
6071+
warnings.simplefilter('always', DeprecationWarning)
60726072
s.convert_objects()
60736073
self.assertEqual(len(w), 1)
60746074

0 commit comments

Comments
 (0)