Цикл For и while выводит более длинный список, чем должен

#python #pandas #numpy #for-loop #while-loop

#python #панды #numpy #for-цикл #цикл while

Вопрос:

Я пытаюсь создать массив чисел (socarray), которые находятся в диапазоне от 0 до 100. Массив инициируется одним элементом (целое число 50).

Добавляемое число равно soc и начинается с 50. Значение soc изменяется в зависимости от значения столбца прогнозирования в фрейме данных (df[‘Pred’] ).

  • Если df[‘Pred’]> 0 и soc <100, то soc = 50 и добавляется к socarray.
  • Если df[‘Pred’] <0 и soc > 0, то soc -= 50 и добавляется к socarray
  • в противном случае мы просто добавляем soc (без добавления или вычитания из значения).

Мой код приведен ниже. Я использую цикл For, цикл while и операторы If .

Диапазон устанавливается на повторение 10 раз (длина фрейма данных). Однако вывод кода представляет собой массив длиной 82.

 soc = 50
socarray = [50]


for i in range(1,10):
    
    counter = 1
    
    while counter < len(df):
        
        if (df.iloc[i]['Pred'] > 0) amp; (soc<100):
            soc  = 50
            socarray.append(soc)
            counter  = 1
            
        elif (df.iloc[i]['Pred'] < 0) amp; (soc>0):
            soc -= 50
            socarray.append(soc)
            counter  = 1
            
        else:
            soc = soc
            socarray.append(soc)
            counter  = 1
            
  

Если я вставляю массив в цикл for, он выводит массив длиной 10, но он не соответствует правильной функциональности (в частности, он не вычитает ‘soc — = 50’, когда это должно быть сделано)

 soc = 50


for i in range(1,len(df)):

        socarray = [50]

    
    counter = 1
    
    while counter < len(df):
        
        if (df.iloc[i]['Pred'] > 0) amp; (soc<100):
            soc  = 50
            socarray.append(soc)
            counter  = 1
            
        elif (df.iloc[i]['Pred MW'] < 0) amp; (soc>0):
            soc -= 50
            socarray.append(soc)
            counter  = 1
            
        else:
            soc = soc
            socarray.append(soc)
            counter  = 1
  

Кто-нибудь может мне помочь?

Ответ №1:

Ваш цикл while выполняется 10 раз. Один раз для каждого диапазона в вашем цикле for. Таким образом, при 82 значениях ваш цикл while выполняется ~ 8 раз для каждой итерации цикла.

В вашем втором примере ваш socarray заполняется последней итерацией цикла for только с момента его инициализации внутри цикла.

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

Вам нужно запустить свой «алгоритм» 10 раз, поэтому цикла for в диапазоне 10 должно быть достаточно.

Попробуйте удалить цикл while и счетчик.

 soc = 50
socarray = [50]


for i in range(1,10):


    if (df.iloc[i]['Pred'] > 0) amp; (soc<100):
        soc  = 50
        socarray.append(soc)
        counter  = 1
        
    elif (df.iloc[i]['Pred'] < 0) amp; (soc>0):
        soc -= 50
        socarray.append(soc)
        counter  = 1
        
    else:
        soc = soc
        socarray.append(soc)
        counter  = 1
  

Ответ №2:

Рассмотрите возможность назначения нового столбца фрейма данных на основе суммы диапазона по условиям. Затем преобразуйте столбец в одномерный массив. Обратите внимание, что все арифметические (т. Е., , - ) и операторы неравенства (т. Е. , < , > ) Были заменены соответствующими функциями Pandas:

 # ASSIGN NEW COLUMN AND FIRST ROW VALUE AS 50
df['soc'] = np.nan
df.loc[0, 'soc'] = 50

# RE-ASSIGN COLUMN BY ROW AND CONDITION
for i in range(len(df)):
   df.loc[i, 'soc'] = np.where((df.loc[i,'Pred'].gt(0)) amp; (df.loc[0:i,'soc'].sum().lt(100)), 
                               df.loc[0:i,'soc'].sum().add(50),
                               np.where((df.loc[i,'Pred'].lt(0)) amp; (df.loc[0:i,'soc'].gt(0)),
                                        df.loc[0:i,'soc'].sum().sub(50), 
                                        df.loc[0:i,'soc'].sum()
                               )
                      )

socarray = df['soc'].to_numpy()