Я новичок в pandas и python, и я борюсь с реализацией циклов в своем коде. Я надеюсь, что кто-то может мне помочь.

У меня есть следующий Dataframe:

import pandas as pd
from pandas import Timestamp

pd.DataFrame({'DateTime': {0: Timestamp('2021-06-13 00:00:00'),
  1: Timestamp('2021-06-13 02:00:00'),
  2: Timestamp('2021-06-13 05:00:00'),
  3: Timestamp('2021-06-13 07:00:00'),
  4: Timestamp('2021-06-13 10:00:00')},
 'actual_value': {0: 180.0949105082311,
  1: 183.93185469787613,
  2: 191.48399886639095,
  3: 188.31358023933768,
  4: 159.32768035801615},
 'forecast_0': {0: nan,
  1: 185.0,
  2: 206.0,
  3: 193.0,
  4: 130.0},
 'forecast_1': {0: 187.0,
  1: 185.0,
  2: 206.0,
  3: 192.0,
  4: 130.0},
 'forecast_2': {0: 186.0,
  1: nan,
  2: 200.0,
  3: 192.0,
  4: nan},
 'forecast_3': {0: 186.0,
  1: 185.0,
  2: 200.0,
  3: 192.0,
  4: 130.0},
 'forecast_4': {0: 186.0,
  1: 183.0,
  2: 200.0,
  3: 188.0,
  4: 130.0}})

             DateTime  actual_value  forecast_0  forecast_1  forecast_2  \
0 2021-06-13 00:00:00    180.094911         NaN       187.0       186.0   
1 2021-06-13 02:00:00    183.931855       185.0       185.0         NaN   
2 2021-06-13 05:00:00    191.483999       206.0       206.0       200.0   
3 2021-06-13 07:00:00    188.313580       193.0       192.0       192.0   
4 2021-06-13 10:00:00    159.327680       130.0       130.0         NaN   

   forecast_3  forecast_4  
0       186.0       186.0  
1       185.0       183.0  
2       200.0       200.0  
3       192.0       188.0  
4       130.0       130.0  

Я хочу создать новый Dataframe или заменить числа в существующем простым расчетом. Я хочу определить отклонение всех значений прогноза относительно фактического значения во втором столбце. Поскольку существует более 40 таких столбцов прогноза, просто слишком много времени требуется, чтобы записать расчет для каждого столбца. Вот почему я хотел бы реализовать цикл. Я пробовал следующий код, который не работал:

for i, col in enumerate(df.columns, -2):
    df[col] = (df[col]-df['actual_value'])/df['actual_value']

Я получаю сообщение об ошибке, что «вычитание» не может использовать операнды с типами dtype('

2
Kats 18 Янв 2022 в 18:21

3 ответа

Лучший ответ

Ошибка 'вычитания' не может использовать операнды с типами dtype('

Чтобы сделать это правильно, вы можете изменить свой цикл на for col in df.columns[2:]:

Несмотря на то, что я согласен с другими решениями, опубликованными здесь, более элегантно сделать это без использования цикла.

1
Pankaj Saini 18 Янв 2022 в 19:01

Вы ищете pd.DataFrame.sub и pd.DataFrame.div:

>>> df.iloc[:, 2:].sub(df["actual_value"], axis=0).div(df["actual_value"], axis=0)
   forecast_0  forecast_1  forecast_2  forecast_3  forecast_4
0         NaN    0.038341    0.032789    0.032789    0.032789
1    0.005807    0.005807         NaN    0.005807   -0.005066
2    0.075808    0.075808    0.044474    0.044474    0.044474
3    0.024886    0.019576    0.019576    0.019576   -0.001665
4   -0.184071   -0.184071         NaN   -0.184071   -0.184071

Эмпирическое правило: если вы хотите работать с DataFrames с помощью циклов, вы делаете что-то не так.

1
tlgs 18 Янв 2022 в 18:38
Большое спасибо за ответ! Это очень помогает.
 – 
Kats
18 Янв 2022 в 21:06

Вы можете использовать str.contains для выбора переменных, содержащих «прогноз», и применить их впоследствии:

df.loc[:,df.columns.str.contains('forecast')].apply(lambda x: (x-df['actual_value'])/df['actual_value'])
Out[0]: 
   forecast_0  forecast_1  forecast_2  forecast_3  forecast_4
0         NaN    0.038341    0.032789    0.032789    0.032789
1    0.005807    0.005807         NaN    0.005807   -0.005066
2    0.075808    0.075808    0.044474    0.044474    0.044474
3    0.024886    0.019576    0.019576    0.019576   -0.001665
4   -0.184071   -0.184071         NaN   -0.184071   -0.184071
1
DHJ 18 Янв 2022 в 18:41
Большое спасибо за ответ! Это очень помогает.
 – 
Kats
18 Янв 2022 в 21:06