Ответ 1
Как преобразовать pandas.Series из
object
dtype вfloat
, а ошибки - в nans?
Начиная с v0.17, convert_objects
устарела.
Чтобы преобразовать серию в числовую, используйте pd.to_numeric
с аргументом errors='coerce'
.
# Setup.
s = pd.Series(['1','2','3','4','.'])
s
0 1
1 2
2 3
3 4
4 .
dtype: object
pd.to_numeric(s, errors='coerce')
0 1.0
1 2.0
2 3.0
3 4.0
4 NaN
dtype: float64
Если вам нужно заполнить NaN
, используйте Series.fillna
.
pd.to_numeric(s, errors='coerce').fillna(0, downcast='infer')
0 1
1 2
2 3
3 4
4 0
dtype: float64
Обратите внимание, что downcast='infer'
будет пытаться по возможности понижать числа с плавающей точкой до целых чисел. Уберите аргумент, если вы этого не хотите.
Начиная с версии 0. 24+, pandas вводит Nullable Integer тип, который позволяет целым числам сосуществовать с NaN. Если в вашем столбце есть целые числа, вы можете использовать
pd.__version__ # '0.24.1' pd.to_numeric(s, errors='coerce').astype('Int32') 0 1 1 2 2 3 3 4 4 NaN dtype: Int32
Есть и другие варианты на выбор, читайте документы, чтобы узнать больше.
Расширение для DataFrames
Если вам нужно расширить это на DataFrames, вам нужно будет применить его к каждой строке. Вы можете сделать это с помощью DataFrame.apply
.
# Setup.
np.random.seed(0)
df = pd.DataFrame({
'A' : np.random.choice(10, 5),
'C' : np.random.choice(10, 5),
'B' : ['1', '###', '...', 50, '234'],
'D' : ['23', '1', '...', '268', '$$']}
)[list('ABCD')]
df
A B C D
0 5 1 9 23
1 0 ### 3 1
2 3 ... 5 ...
3 3 50 2 268
4 7 234 4 $$
df.dtypes
A int64
B object
C int64
D object
dtype: object
df2 = df.apply(pd.to_numeric, errors='coerce')
df2
A B C D
0 5 1.0 9 23.0
1 0 NaN 3 1.0
2 3 NaN 5 NaN
3 3 50.0 2 268.0
4 7 234.0 4 NaN
df2.dtypes
A int64
B float64
C int64
D float64
dtype: object
Вы также можете сделать это с DataFrame.transform
; хотя мои тесты показывают, что это немного медленнее:
df.transform(pd.to_numeric, errors='coerce')
A B C D
0 5 1.0 9 23.0
1 0 NaN 3 1.0
2 3 NaN 5 NaN
3 3 50.0 2 268.0
4 7 234.0 4 NaN
Если у вас много столбцов (числовых; не числовых), вы можете сделать это немного более производительным, применив pd.to_numeric
к нечисловым столбцам.
df.dtypes.eq(object)
A False
B True
C False
D True
dtype: bool
cols = df.columns[df.dtypes.eq(object)]
# Actually, 'cols' can be any list of columns you need to convert.
cols
# Index(['B', 'D'], dtype='object')
df[cols] = df[cols].apply(pd.to_numeric, errors='coerce')
# Alternatively,
# for c in cols:
# df[c] = pd.to_numeric(df[c], errors='coerce')
df
A B C D
0 5 1.0 9 23.0
1 0 NaN 3 1.0
2 3 NaN 5 NaN
3 3 50.0 2 268.0
4 7 234.0 4 NaN
Применение pd.to_numeric
вдоль столбцов (т. pd.to_numeric
axis=0
, по умолчанию) должно быть немного быстрее для длинных фреймов данных.