#python #pandas
#python #pandas
Вопрос:
Я создал синтетические данные, используя этот код-
# x variable
x_value = np.linspace(0,2*np.pi,1000)
# y variable
for i in x_value:
y_value = np.sin(x_value)
# create a dataframe with the x and y values
data = pd.DataFrame({'x':x_value, 'y':y_value})
Я хотел бы создать третий столбец для производной от x (cos(x_value)), вычисляемой вручную с использованием метода конечных разностей — где для значения 1-й строки я должен использовать метод прямой разности, последней строки — обратной разности, а для остальных использовать центральную разность.
Мой код выглядит так —
# differnce for xvalue, delta_x
data['delta_x']= data['x'].diff(1) # resukts in 0.006289
# create an empty column
data['deriv'] = ''
# function for Central difference for row 2 to 2nd last row
for i in range(1,len(data)-1):
data['deriv'][i] = (data['y'][i 1]-data['y'][i-1])/(2*0.006289)
# for the 1st row - forward difference
data['deriv'][0] = (data['y'][1]-data['y'][0])/0.006289
# for the last row - backward difference
data['deriv'].iloc[-1] = (data['y'].iloc[-1]-data['y'].iloc[-2])/0.006289
Я получаю желаемый результат (истинная производная и вычисленные производные совпадают), но я получаю это предупреждение для методов разницы- SettingWithCopyWarning:
Значение пытается быть установлено на копии фрагмента из фрейма данных
Кроме того, я ищу эффективный способ написания этого кода.
Заранее большое спасибо.
Ответ №1:
Если вам интересно, почему вы получаете ошибку, вы можете подробнее прочитать о возврате представления и копии массива numpy.
Чтобы улучшить ваш код в целом, я бы рекомендовал попробовать использовать векторные операции numpy, а не использовать циклы for .
Примером может служить вычисление вашего y_value . Я хотел бы отметить, что у вас есть цикл for, в котором вы повторно переназначаете
y_value = np.sin(x_value)
даже не используя переменную i. Я бы полностью удалил цикл for, чтобы сэкономить время и ускорить работу.
Ответ №2:
Объяснение
Не используйте iloc
метод для присвоения значения, пожалуйста, используйте at
метод.
Вот так data['deriv'].at[-1] = (data['y'].iloc[-1]-data['y'].iloc[-2])/0.006289
ссылка на pandas.DataFrame.at
Модифицированный код
# differnce for xvalue, delta_x
data['delta_x']= data['x'].diff(1) # resukts in 0.006289
# create an empty column
data['deriv'] = ''
# function for Central difference for row 2 to 2nd last row
for i in range(1,len(data)-1):
data['deriv'].at[i] = (data['y'][i 1]-data['y'][i-1])/(2*0.006289)
# for the 1st row - forward difference
data['deriv'].at[0] = (data['y'][1]-data['y'][0])/0.006289
# for the last row - backward difference
data['deriv'].at[-1] = (data['y'].iloc[-1]-data['y'].iloc[-2])/0.006289
Результат
Комментарии:
1. Спасибо Tao-Lung. Этот метод очень хорошо работал для первой строки, но при запуске
data['deriv'].at[-1] = (data['y'].iloc[-1]-data['y'].iloc[-2])/0.006289
я получаю дополнительную строку с индексом -1. Если я использую реальную индексацию для последних двух строк, т.Е. 999 и 998, тогда это работает. Есть ли другой способ получить доступ к последней строке, кроме [-1]?2. Я попробовал ваш код и не столкнулся с такой же проблемой.
3. Спасибо Tao-Lung за модификацию кода и обмен им со мной. Как вы можете видеть на выходе, для столбца ‘deriv’ для последней строки нет значения (индекс 999). Когда я делаю то же самое, что и вы, я получаю дополнительную строку (в конце) с индексом -1. Я хотел бы вставить изображение вывода, но я не знаю, как вставить изображение — я новичок в этом. Еще раз спасибо, что помогли мне с этим. Я действительно ценю вашу помощь.