Mark D
Mark D

Reputation: 167

Multiple for loops to create a pandas dataframe

I am trying to create a pandas dataframe that looks like this:

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

but the closest I can get is the code below which returns a dataframe with only one column (which is the list from the last iteration through the ctr1 loop)

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})

Can anyone help?

Upvotes: 0

Views: 1328

Answers (4)

Mark D
Mark D

Reputation: 167

As mentioned, for completeness, I have posted an answer to my question that works with a larger weather array. The only difference is that I did the rounding earlier in the code:

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

Upvotes: 0

Mateus Reis
Mateus Reis

Reputation: 306

df_final is getting only 3 elements because it's at the same indentation level as for ctr2 in weather, so it's getting reassigned every outer loop. Although, if you fix that, you'll get a dataframe that's only a single long column: you only have a single slope_list getting appended to that turns into a dataframe at the end.

This is how I would solve that without changing your assignment method:

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

Although you should keep in mind that unless you know exactly what you're doing, making loops and nested loops when working with pandas usually means you're missing a much easier and better way to go about things.

Upvotes: 2

Alexey S. Kiselev
Alexey S. Kiselev

Reputation: 89

You can try directly assign values in DataFrame. Just create empty DataFrame with index=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

Upvotes: 1

kosist
kosist

Reputation: 3057

slope_list = [] resets resulting list at each iteration, so just the last one remains. You need to define result list outside the outer loop, and append subresults to it.

Upvotes: 0

Related Questions