Python Pandas Dataframe: по возможности конвертировать строки в числовые;иначе сохраните строковые значения - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть Pandas Dataframe, в котором есть столбцы, которые выглядят примерно так:

df:

Column0   Column1     Column2
'MSC'       '1'        'R2'
'MIS'       'Tuesday'  '22'
'13'        'Finance'  'Monday'

Таким образом, в целом, в этих столбцах представлены фактические строки, а также числовые значения (целые числа) в строковом формате.

Я нашел этот хороший пост о pd.to_numeric и astype() методах, но я не могу понять, смогу ли я использовать их в моем случае.

Использование:

pd.to_numeric(df, errors = 'ignore')

просто приводит к пропуску целых столбцов.Вместо того, чтобы пропустить целые столбцы, я хочу пропустить только строки в тех столбцах, которые не могут быть преобразованы, перейти к следующей записи и попытаться преобразовать следующую строку.

Итак, в конце концов, мойдатафрейм будет выглядеть следующим образом:

df:

Column0   Column1     Column2
'MSC'       1          'R2'
'MIS'      'Tuesday'    22
 13        'Finance'  'Monday'

Может быть, есть эффективный способ циклического перебора этих столбцов и достижения этого?

С наилучшими пожеланиями, январь

РЕДАКТИРОВАТЬ: Спасибо за все ваши предложения!Поскольку я еще новичок в питоне, ответы @coldspeed и @sacul для меня легче понять, поэтому я пойду с одним из них!

Ответы [ 4 ]

0 голосов
/ 05 декабря 2018

Использование to_numeric + ignore

df=df.applymap(lambda x : pd.to_numeric(x,errors='ignore'))
df
  Column0  Column1 Column2
0     MSC        1      R2
1     MIS  Tuesday      22
2      13  Finance  Monday
df.applymap(type)
                 Column0                Column1                Column2
0          <class 'str'>  <class 'numpy.int64'>          <class 'str'>
1          <class 'str'>          <class 'str'>  <class 'numpy.int64'>
2  <class 'numpy.int64'>          <class 'str'>          <class 'str'>
0 голосов
/ 05 декабря 2018

Я бы применил pd.to_numeric с errors='coerce' и update исходным кадром данных в соответствии с результатами (см. Предостережения в комментариях):

# show original string type:
df.loc[0,'Column1']
# '1'

df.update(df.apply(pd.to_numeric, errors='coerce'))

>>> df
  Column0  Column1 Column2
0     MSC        1      R2
1     MIS  Tuesday      22
2      13  Finance  Monday

# show updated float type:
df.loc[0,'Column1']
# 1.0
0 голосов
/ 05 декабря 2018

Или вы можете просто использовать isnumeric() метод str.Мне это нравится, потому что синтаксис ясен, хотя, согласно комментарию coldspeed, это может стать очень медленным при большом df.

df = df.applymap(lambda x: int(x) if x.isnumeric() else x)

Пример:

In [1]: import pandas as pd

In [2]: df = pd.DataFrame([['a','b','c'],['1','1a','c']],columns=['Col1','Col2','Col3'])

In [3]: df
Out[3]:
  Col1 Col2 Col3
0    a    b    c
1    1   1a    c

In [4]: df.Col1.map(lambda x: int(x) if x.isnumeric() else x)
Out[4]:
0    a
1    1
Name: Col1, dtype: object
0 голосов
/ 05 декабря 2018

100% согласны с комментариями - смешивать dtypes в столбцах - ужасная идея, с точки зрения производительности.

Для справки, однако, я бы сделал это с pd.to_numeric и fillna:

df2 = df.apply(pd.to_numeric, errors='coerce').fillna(df)
print(df2)
  Column0  Column1 Column2
0     MSC        1      R2
1     MIS  Tuesday      22
2      13  Finance  Monday

Столбцы приводятся к типу object d, чтобы предотвратить принуждение.Вы можете видеть это, когда извлекаете values:

print(df2.values.tolist())
[['MSC', 1.0, 'R2'], ['MIS', 'Tuesday', 22.0], [13.0, 'Finance', 'Monday']]
...