Как вычислить производную массива, используя конечную разность?

#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. Я хотел бы вставить изображение вывода, но я не знаю, как вставить изображение — я новичок в этом. Еще раз спасибо, что помогли мне с этим. Я действительно ценю вашу помощь.