Подтвердить что ты не робот

Конвертировать целые pandas данные в целые числа в pandas (0.17.0)

Мой вопрос очень похож на на этот, но мне нужно преобразовать весь весь фрейм данных, а не просто серию. Функция to_numeric работает только по одной серии за раз и не является хорошей заменой устаревшей команде convert_objects. Есть ли способ получить похожие результаты в команде convert_objects(convert_numeric=True) в новой версии pandas?

Спасибо Майку Мюллеру за ваш пример. df.apply(pd.to_numeric) работает очень хорошо, если значения могут быть преобразованы в целые числа. Что делать, если в моем кадре данных были строки, которые не могли быть преобразованы в целые числа? Пример:

df = pd.DataFrame({'ints': ['3', '5'], 'Words': ['Kobe', 'Bryant']})
df.dtypes
Out[59]: 
Words    object
ints     object
dtype: object

Затем я мог запустить устаревшую функцию и получить:

df = df.convert_objects(convert_numeric=True)
df.dtypes
Out[60]: 
Words    object
ints      int64
dtype: object

Выполнение команды apply дает мне ошибки, даже при попытке и исключении обработки.

4b9b3361

Ответ 1

Все колонны конвертируемые

Вы можете применить функцию ко всем столбцам:

df.apply(pd.to_numeric)

Пример:

>>> df = pd.DataFrame({'a': ['1', '2'], 
                       'b': ['45.8', '73.9'],
                       'c': [10.5, 3.7]})

>>> df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2 entries, 0 to 1
Data columns (total 3 columns):
a    2 non-null object
b    2 non-null object
c    2 non-null float64
dtypes: float64(1), object(2)
memory usage: 64.0+ bytes

>>> df.apply(pd.to_numeric).info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2 entries, 0 to 1
Data columns (total 3 columns):
a    2 non-null int64
b    2 non-null float64
c    2 non-null float64
dtypes: float64(2), int64(1)
memory usage: 64.0 bytes

Не все колонки конвертируемы

pd.to_numeric имеет errors аргумента ключевого слова:

  Signature: pd.to_numeric(arg, errors='raise')
  Docstring:
  Convert argument to a numeric type.

Parameters
----------
arg : list, tuple or array of objects, or Series
errors : {'ignore', 'raise', 'coerce'}, default 'raise'
    - If 'raise', then invalid parsing will raise an exception
    - If 'coerce', then invalid parsing will be set as NaN
    - If 'ignore', then invalid parsing will return the input

Установка значения ignore вернет столбец без изменений, если он не может быть преобразован в числовой тип.

Как отметил Антон Протопопов, самый элегантный способ - указать ignore качестве ключевого аргумента для apply():

>>> df = pd.DataFrame({'ints': ['3', '5'], 'Words': ['Kobe', 'Bryant']})
>>> df.apply(pd.to_numeric, errors='ignore').info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2 entries, 0 to 1
Data columns (total 2 columns):
Words    2 non-null object
ints     2 non-null int64
dtypes: int64(1), object(1)
memory usage: 48.0+ bytes

Мой ранее предложенный способ, использующий частичное из модуля functools, является более подробным:

>>> from functools import partial
>>> df = pd.DataFrame({'ints': ['3', '5'], 
                       'Words': ['Kobe', 'Bryant']})
>>> df.apply(partial(pd.to_numeric, errors='ignore')).info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2 entries, 0 to 1
Data columns (total 2 columns):
Words    2 non-null object
ints     2 non-null int64
dtypes: int64(1), object(1)
memory usage: 48.0+ bytes

Ответ 2

apply() pd.to_numeric с errors='ignore' и назначьте его обратно в DataFrame:

df = pd.DataFrame({'ints': ['3', '5'], 'Words': ['Kobe', 'Bryant']})
print ("Orig: \n",df.dtypes)

df.apply(pd.to_numeric, errors='ignore')
print ("\nto_numeric: \n",df.dtypes)

df = df.apply(pd.to_numeric, errors='ignore')
print ("\nto_numeric with assign: \n",df.dtypes)

Выход:

Orig: 
 ints     object
Words    object
dtype: object

to_numeric: 
 ints     object
Words    object
dtype: object

to_numeric with assign: 
 ints      int64
Words    object
dtype: object