Skip to content

Commit

Permalink
CLN: PEP 8 improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Sheppard committed Jul 13, 2015
1 parent 0727803 commit e9d6678
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 21 deletions.
16 changes: 10 additions & 6 deletions doc/source/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1524,13 +1524,15 @@ object conversion

.. note::

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

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

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

gotchas
~~~~~~~
Expand Down
33 changes: 30 additions & 3 deletions doc/source/whatsnew/v0.17.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Backwards incompatible API changes

.. _whatsnew_0170.api_breaking.other:

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

.. ipython:: python

df = pd.DataFrame({'i': ['1','2'], 'f': ['apple', '4.2']})
df = pd.DataFrame({'i': ['1','2'],
'f': ['apple', '4.2'],
's': ['apple','banana']})
df

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

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

- The new default behavior for ``DataFrame.convert_objects`` is to do nothing,
and so it is necessary to pass at least one conversion target when calling.
- In earlier versions of pandas, ``DataFrame.convert_objects`` would not coerce
numeric types when there were no values convertible to a numeric type. For example,

.. code-block:: python

In [1]: df = pd.DataFrame({'s': ['a','b']})
In [2]: df.convert_objects(convert_numeric='coerce')
Out[2]:
s
0 a
1 b

returns the original DataFrame with no conversion. This change alters
this behavior so that

.. ipython:: python

pd.DataFrame({'s': ['a','b']})
df.convert_objects(numeric=True, coerce=True)

converts all non-number-like strings to ``NaN``.

- In earlier versions of pandas, the default behavior was to try and convert
datetimes and timestamps. The new default is for ``DataFrame.convert_objects``
to do nothing, and so it is necessary to pass at least one conversion target
in the method call.


Other API Changes
Expand Down
13 changes: 9 additions & 4 deletions pandas/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1892,15 +1892,18 @@ def _possibly_convert_objects(values,
datetime=True,
numeric=True,
timedelta=True,
coerce=False):
coerce=False,
copy=True):
""" if we have an object dtype, try to coerce dates and/or numbers """

conversion_count = sum((datetime, numeric, timedelta))
if conversion_count == 0:
import warnings
warnings.warn('Must explicitly pass type for conversion. Original '
'value returned.', RuntimeWarning)
return values
warnings.warn('Must explicitly pass type for conversion. Defaulting to '
'pre-0.17 behavior where datetime=True, numeric=True, '
'timedelta=True and coerce=False', DeprecationWarning)
datetime = numeric = timedelta = True
coerce = False

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

# If 1 flag is coerce, ensure 2 others are False
Expand Down Expand Up @@ -1942,6 +1946,7 @@ def _possibly_convert_objects(values,
coerce_numeric=True)
# If all NaNs, then do not-alter
values = converted if not isnull(converted).all() else values
values = values.copy() if copy else values
except:
pass

Expand Down
6 changes: 4 additions & 2 deletions pandas/core/internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,8 @@ def convert(self, datetime=True, numeric=True, timedelta=True, coerce=False,
datetime=datetime,
numeric=numeric,
timedelta=timedelta,
coerce=coerce
coerce=coerce,
copy=copy
).reshape(values.shape)
values = _block_shape(values, ndim=self.ndim)
newb = make_block(values,
Expand All @@ -1490,7 +1491,8 @@ def convert(self, datetime=True, numeric=True, timedelta=True, coerce=False,
datetime=datetime,
numeric=numeric,
timedelta=timedelta,
coerce=coerce
coerce=coerce,
copy=copy
).reshape(self.values.shape)
blocks.append(make_block(values,
ndim=self.ndim, placement=self.mgr_locs))
Expand Down
18 changes: 17 additions & 1 deletion pandas/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import re

import nose
from nose.tools import assert_equal
from nose.tools import assert_equal, assert_true
import numpy as np
from pandas.tslib import iNaT, NaT
from pandas import Series, DataFrame, date_range, DatetimeIndex, Timestamp, Float64Index
Expand Down Expand Up @@ -1026,6 +1026,22 @@ def test_dict_compat():
assert(com._dict_compat(expected) == expected)
assert(com._dict_compat(data_unchanged) == data_unchanged)

def test_possibly_convert_objects_copy():
values = np.array([1, 2])

out = com._possibly_convert_objects(values, copy=False)
assert_true(values is out)

out = com._possibly_convert_objects(values, copy=True)
assert_true(values is not out)

values = np.array(['apply','banana'])
out = com._possibly_convert_objects(values, copy=False)
assert_true(values is out)

out = com._possibly_convert_objects(values, copy=True)
assert_true(values is not out)


if __name__ == '__main__':
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
Expand Down
10 changes: 5 additions & 5 deletions pandas/tests/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -5959,23 +5959,23 @@ def test_convert_objects(self):

# test pass-through and non-conversion when other types selected
s = Series(['1.0','2.0','3.0'])
results = s.convert_objects(True,True,True)
results = s.convert_objects(datetime=True, numeric=True, timedelta=True)
expected = Series([1.0,2.0,3.0])
assert_series_equal(results, expected)
results = s.convert_objects(True,False,True)
assert_series_equal(results, s)

s = Series([datetime(2001, 1, 1, 0, 0),datetime(2001, 1, 1, 0, 0)],
dtype='O')
results = s.convert_objects(True,True,True)
results = s.convert_objects(datetime=True, numeric=True, timedelta=True)
expected = Series([datetime(2001, 1, 1, 0, 0),datetime(2001, 1, 1, 0, 0)])
assert_series_equal(results, expected)
results = s.convert_objects(False,True,True)
results = s.convert_objects(datetime=False,numeric=True,timedelta=True)
assert_series_equal(results, s)

td = datetime(2001, 1, 1, 0, 0) - datetime(2000, 1, 1, 0, 0)
s = Series([td, td], dtype='O')
results = s.convert_objects(True,True,True)
results = s.convert_objects(datetime=True, numeric=True, timedelta=True)
expected = Series([td, td])
assert_series_equal(results, expected)
results = s.convert_objects(True,True,False)
Expand Down Expand Up @@ -6068,7 +6068,7 @@ def test_convert_objects(self):
def test_convert_objects_no_arg_warning(self):
s = Series(['1.0','2'])
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always', RuntimeWarning)
warnings.simplefilter('always', DeprecationWarning)
s.convert_objects()
self.assertEqual(len(w), 1)

Expand Down

0 comments on commit e9d6678

Please sign in to comment.