#python #pandas #dataframe
Вопрос:
Я хочу преобразовать все мои столбцы в число с плавающей запятой, если в определенном столбце указаны цифры.
Вот что я пробовал до сих пор:
for columns in range(len(df.columns)):
for rows in range(len(df)):
if str(df.iloc[rows,columns]).replace('.','',1).isdigit() == True:
df.iloc[rows,columns] = float(df.iloc[rows,columns])
Он работает хорошо, но для его запуска требуется много времени из-за размера фрейма данных. Есть ли у кого-нибудь идеи для более простого и эффективного кода?
Комментарии:
1. привет! можете ли вы опубликовать пример (в коде!) входного набора данных и ожидаемого результата?
Ответ №1:
Отвечает ли это на ваш вопрос?
df = df.apply(lambda i: i.apply(lambda x: float(x) if str(x).replace('.','',1).isdigit() else x))
Комментарии:
1. это работает! просто интересно, как использование лямбда-функции приводит к более быстрому выполнению по сравнению с циклами?
Ответ №2:
Вы можете применить pandas.to_numeric
его ко всем столбцам. При указании errors='coerce'
нечисловых значений они будут преобразованы в NaN. https://pandas.pydata.org/docs/reference/api/pandas.to_numeric.html
Затем передайте fillna
фрейм данных, чтобы заполнить NAN исходными нечисловыми значениями.
Это должно быть быстрее, чем другой ответ для больших фреймов данных.
>>> df = pd.DataFrame([["x", 1, "2.1"], [3.2, "y", "5."]], columns=list("ABC"))
>>> df
A B C
0 x 1 2.1
1 3.2 y 5.
>>> df = (
df.apply(pd.to_numeric, errors='coerce', downcast='float')
.fillna(df)
)
>>> df
A B C
0 x 1 2.1
1 3.2 y 5
# confirm that the values are floats
>>> type(df.at[0,'C'])
float
>>> type(df.at[1,'C'])
float