Множество циклов for для создания фрейма данных pandas

1

Я пытаюсь создать рамку данных pandas, которая выглядит так:

          -5      0      5
index                     
-5       NaN  slope  slope
 0     slope    NaN  slope
 5     slope  slope    NaN

но ближайший я могу получить код ниже, который возвращает dataframe только с одним столбцом (который является списком из последней итерации в цикле ctr1)

weather = np.linspace(-5, 5, 3)

for ctr1 in weather:
    slope_list = []
    X1 = round(ctr1,1)
    for ctr2 in weather:
        X2 = round(ctr2,1)

        Y1 = regressor[0] * X1**3 + \
        regressor[1] * X1**2 + \
        regressor[2] * X1 + \
        regressor[3] 

        Y2 = regressor[0] * X2**3 + \
        regressor[1] * X2**2 + \
        regressor[2] * X2 + \
        regressor[3]

        slope = (Y2-Y1)/(X2-X1)
        slope_list.append(slope)

    df_final = pd.DataFrame({X1:slope_list})

Может ли кто-нибудь помочь?

  • 0
    Пожалуйста, предоставьте ожидаемый результат.
  • 0
    Привет, andrew_reece, ожидаемый результат такой же, как я показал справа вверху, где каждый «уклон» - это число (на основе расчета с использованием X1, X2, Y1, Y2).
Теги:
pandas
for-loop

4 ответа

1
Лучший ответ

Вы можете попробовать напрямую назначать значения в DataFrame. Просто создайте пустой DataFrame с индексом = weather:

import numpy as np
weather = np.linspace(-5, 5, 3)
df_final = pd.DataFrame([], index=weather)
for ctr1 in weather:
    X1 = round(ctr1,1)
    for ctr2 in weather:
        X2 = round(ctr2,1)

        Y1 = regressor[0] * X1**3 + \
        regressor[1] * X1**2 + \
        regressor[2] * X1 + \
        regressor[3] 

        Y2 = regressor[0] * X2**3 + \
        regressor[1] * X2**2 + \
        regressor[2] * X2 + \
        regressor[3]

       slope = (Y2-Y1)/(X2-X1)

       df_final.loc[X1, X2] = np.NaN if X1 == X2 else slope
  • 1
    Для целочисленной позиционной установки я рекомендую использовать более эффективный .iat вместо .loc .
  • 1
    Привет Алексей, спасибо за ваше решение. Для полноты я подумал, что предоставлю единственное обновление, которое мне нужно было добавить, чтобы оно идеально работало для большого массива погоды. Я добавил собственное решение, основанное в основном на вашем коде.
2

df_final получает только 3 элемента, потому что на том же уровне отступов, что и for ctr2 in weather, поэтому он получает переназначение каждого внешнего цикла. Хотя, если вы исправите это, вы получите фреймворк данных, который содержит только один длинный столбец: у вас есть только один slope_list, добавляемый к нему, который в конце концов превращается в slope_list.

Вот как я решил бы это без изменения метода назначения:

weather = np.linspace(-5, 5, 3)
slope_list = []
for ctr1 in weather:
X1 = round(ctr1,1)
for ctr2 in weather:
    X2 = round(ctr2,1)

    Y1 = regressor[0] * X1**3 + \
    regressor[1] * X1**2 + \
    regressor[2] * X1 + \
    regressor[3] 

    Y2 = regressor[0] * X2**3 + \
    regressor[1] * X2**2 + \
    regressor[2] * X2 + \
    regressor[3]

    slope = (Y2-Y1)/(X2-X1)
    slope_list.append(slope)


#make it 3 columns and 3 rows as intended
slope_list = np.array(slope_list).reshape(3, 3)
#make the dataframe
df_final = pd.DataFrame({X1:slope_list})
#manually add the desired row and column indexes
df_final = df.set_index(weather)
df_final.columns = weather

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

0

Как уже упоминалось, для полноты я отправил ответ на свой вопрос, который работает с большим массивом погоды. Единственное различие заключается в том, что я сделал округление ранее в коде:

weather = np.round(np.linspace(-5, 35, 401), decimals = 1)
df_final = pd.DataFrame([], index=weather)
for ctr1 in weather:
    X1 = ctr1
    for ctr2 in weather:
        X2 = ctr2

        Y1 = regressor[0] * X1**3 + \
        regressor[1] * X1**2 + \
        regressor[2] * X1 + \
        regressor[3] 

        Y2 = regressor[0] * X2**3 + \
        regressor[1] * X2**2 + \
        regressor[2] * X2 + \
        regressor[3]

        slope = (Y2-Y1)/(X2-X1)

        df_final.loc[X1, X2] = np.NaN if X1 == X2 else slope
0

slope_list = [] сбрасывает результирующий список на каждой итерации, поэтому остается только последний. Вам нужно определить список результатов вне внешнего цикла и добавить к нему подвыборы.

  • 0
    Благодаря Kosist, причина, по которой я сбрасываю slope_list во внешнем цикле, заключается в том, что я хочу, чтобы в каждом столбце было только 3 строки. Если я установлю это вне внешнего цикла, я получу список с 9 значениями.
  • 0
    Не могли бы вы также опубликовать данные regressor (лучше, чем полный код), чтобы мы могли попытаться запустить код? B / C теперь вы сбрасываете данные этим, и поэтому есть только один столбец с последней итерацией ctr1.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню