Python: How to use dataframe data to calculate a new column?

Viewed 28

I was given a script that has to use as input data four columns of my dataframe to calculate a new volume flow rate and energy use. I imported the Dataframe, but when I run the script, no new column is added to the df.

I changed the variables in the functions so the name of my df headers are the same in the script (therefore they can be used as input data). However still no column is added and I do not know what I am doing wrong.

The original script and the modified one are below:


 

import pandas as pd

 

import math

 

import pickle

 

import pytz

 

Ventil_Spec = [[0, 17.39130435, 34.7826087, 45.65217391, 65.2173913, 78.26086957, 95.65217391, 121.7391304, 139.1304348,

 

                165.2173913, 186.9565217],

 

               [0, 17.39130435, 34.7826087, 60.86956522, 86.95652174, 106.5217391, 139.1304348, 171.7391304, 200,

 

                230.4347826, 265.2173913],

 

               [0, 23.91304348, 43.47826087, 65.2173913, 100, 117.3913043, 147.826087, 178.2608696, 210.8695652,

 

                236.9565217, 269.5652174]]  # Air flow through the FVU in m3/h

 

def bilinear_interpolation(x, y, points=None):

 

    ''' based on https://stackoverflow.com/a/8662355

 

    x is the Fan power, y the Heat recovery opening, both in the case of a closed secondary air damper

 

    This function only interpolates the volume flow rate from the given Ventil_Spec list, using the

 

    Fan power and Heat recovery opening

 

    Interpolate (x,y) from values associated with four points.

 

    The four points are a list of four triplets:  (x, y, value).

 

    The four points can be in any order.  They should form a rectangle.

 

        >>> bilinear_interpolation(12, 5.5,

 

        ...                        [(10, 4, 100),

 

        ...                         (20, 4, 200),

 

        ...                         (10, 6, 150),

 

        ...                         (20, 6, 300)])

 

        165.0

 

    :param x:       float   Fan Power in percent

 

    :param y:       float   Heat recovery opening position in percent

 

    :param points:  list    List of corner points for bilinear interpolation

 

    :return:

 

    '''

 

    if math.isnan(x):

 

        return x

 

    if math.isnan(y):

 

        y = 0

 

    # See formula at:  http://en.wikipedia.org/wiki/Bilinear_interpolation

 

    def points_fvu_volume_flow(x_fan):

 

        # returns the corner points for the bilinear interpolation for the EBC FVUs, depending on the fan power,

 

        # in the case of a closed secondary air damper

 

        if x_fan > 100:

 

            x_fan = 100

 

        x1_fan = int(x_fan / 10)

 

        x2_fan = math.ceil(x_fan / 10)

 

        z1 = Ventil_Spec[1][x1_fan]

 

        z2 = Ventil_Spec[1][x2_fan]

 

        z3 = Ventil_Spec[2][x1_fan]

 

        z4 = Ventil_Spec[2][x2_fan]

 

        return [(x1_fan * 10, 0, z1), (x2_fan * 10, 0, z2), (x1_fan * 10, 100, z3), (x2_fan * 10, 100, z4)]

 

    if points is None:

 

        points = points_fvu_volume_flow(x)

 

    points = sorted(points)  # order points by x, then by y

 

    (x1, y1, q11), (_x1, y2, q12), (x2, _y1, q21), (_x2, _y2, q22) = points

 

    # if x1 != _x1 or x2 != _x2 or y1 != _y1 or y2 != _y2:

 

    #     raise ValueError('points do not form a rectangle')

 

    # if not x1 <= x <= x2 or not y1 <= y <= y2:

 

    #     raise ValueError('(x, y) not within the rectangle')

 

    if x1 == x2 and _x1 == _x2 and x1 == _x1:

 

        y_top = max(q11, q12, q21, q22)

 

        y_bot = min(q11, q12, q21, q22)

 

        return (y_top - y_bot) / 100 * y + y_bot

 

    if y1 == y2 and _y1 == _y2 and y1 == _y1:

 

        x_top = max(q11, q12, q21, q22)

 

        x_bot = min(q11, q12, q21, q22)

 

        return (x_top - x_bot) / 100 * x + x_bot

 

    return (q11 * (x2 - x) * (y2 - y) +

 

            q21 * (x - x1) * (y2 - y) +

 

           q12 * (x2 - x) * (y - y1) +

 

            q22 * (x - x1) * (y - y1)

 

            ) / ((x2 - x1) * (y2 - y1) + 0.0)

 


 

def calc_energy_use(df):

 

    '''

 

    :param df: pandas DataFrame     Dataframe mit zumindest den folgenden Spalten:

 

                                    Fan_Power:          float   Zuluftventilatorleistung in %

 

                                    Heat_Recovery:      float   Wärmerückgewinnungsklappenstellung in %

 

                                    #####SEC_Air_Damper:     float   Umluftklappenstellung in % [nur fuer Frischluftanteil benötigt]

 

                                    Inlet_Temperature:  float   Temperatur der Zuluft hinterm Heizregister

 

                                    Mixed_Temperature:  float   Temperatur der Zuluft vor dem Heizregister

 

    :return:   pandas DataFrame     Eingangs-DataFrame mit zwei zusätzlichen Spalten:

 

                                    Volume_Flow:        float   Luftvolumenstrom Lufteinlass in m³/h

 

                                    Energy_Flow:        float   Kühl-/Heizleistung des Kühl-/Heizregisters in kW

 

    '''

 

    try:

 

        df['Volume_Flow'] = df.apply(lambda row: bilinear_interpolation(row['Fan_Power'], row['Heat_Recovery']), axis=1)

 

        #df['Fresh_Air_Flow'] = df.apply(lambda row: V_i_cond(row['SEC_Air_Damper'],

 

        #                                                     row['Heat_Recovery'],

 

        #                                                     row['Fan_Power']), axis=1)

 

                            # Volume_Flow [m³/h] * rho_L [kg/m³] * h/s * (T_out-T_in) [K] * cp_L [KJ/kg*K]

 

        df['Energy_Flow'] = df.apply(lambda row: row['Volume_Flow'] * 1.2041/3600 *

 

                                                 (row['Inlet_Temperature'] - row['Mixed_Temperature']) * 1.01, axis=1)

 

        return df

 

    except:

 

        df['Volume_Flow'] = NaN

 

        df['Energy_Flow'] = NaN

 

        return df

modified script

from numpy.core.numeric import NaN

 

import pandas as pd

 

import math

 

import pickle

 

import pytz

df = pd.read_csv('(.....)/Tnew.csv')


Ventil_Spec = [[0, 17.39130435, 34.7826087, 45.65217391, 65.2173913, 78.26086957, 95.65217391, 121.7391304, 139.1304348,

 

                165.2173913, 186.9565217],

 

               [0, 17.39130435, 34.7826087, 60.86956522, 86.95652174, 106.5217391, 139.1304348, 171.7391304, 200,

 

                230.4347826, 265.2173913],

 

               [0, 23.91304348, 43.47826087, 65.2173913, 100, 117.3913043, 147.826087, 178.2608696, 210.8695652,

 

                236.9565217, 269.5652174]]  # Air flow through the FVU in m3/h

 

#def bilinear_interpolation(x, y, points=None):
def bilinear_interpolation(Fan_Power, Heat_Recovery, points = None):
 

    ''' based on https://stackoverflow.com/a/8662355

 

    x is the Fan power, y the Heat recovery opening, both in the case of a closed secondary air damper

 

    This function only interpolates the volume flow rate from the given Ventil_Spec list, using the

 

    Fan power and Heat recovery opening

 

    Interpolate (x,y) from values associated with four points.

 

    The four points are a list of four triplets:  (x, y, value).

 

    The four points can be in any order.  They should form a rectangle.

 

        >>> bilinear_interpolation(12, 5.5,

 

        ...                        [(10, 4, 100),

 

        ...                         (20, 4, 200),

 

        ...                         (10, 6, 150),

 

        ...                         (20, 6, 300)])

 

        165.0

 

    :param x:       float   Fan Power in percent

 

    :param y:       float   Heat recovery opening position in percent

 

    :param points:  list    List of corner points for bilinear interpolation

 

    :return:

 

    '''

 

    if math.isnan(Fan_Power):

 

        return Fan_Power

 

    if math.isnan(Heat_Recovery):

 

        Heat_Recovery = 0

 

    # See formula at:  http://en.wikipedia.org/wiki/Bilinear_interpolation

 

   # def points_fvu_volume_flow(x_fan):
    def points_fvu_volume_flow(Fan_Power):

 

        # returns the corner points for the bilinear interpolation for the EBC FVUs, depending on the fan power,

 

        # in the case of a closed secondary air damper

 

        if Fan_Power > 100:

 

            Fan_Power = 100

 

        x1_fan = int(Fan_Power / 10)

 

        x2_fan = math.ceil(Fan_Power / 10)

 

        z1 = Ventil_Spec[1][x1_fan]

 

        z2 = Ventil_Spec[1][x2_fan]

 

        z3 = Ventil_Spec[2][x1_fan]

 

        z4 = Ventil_Spec[2][x2_fan]

 

        return [(x1_fan * 10, 0, z1), (x2_fan * 10, 0, z2), (x1_fan * 10, 100, z3), (x2_fan * 10, 100, z4)]

 

    if points is None:

 

        points = points_fvu_volume_flow(Fan_Power)

 

    points = sorted(points)  # order points by x, then by y

 

    (x1, y1, q11), (_x1, y2, q12), (x2, _y1, q21), (_x2, _y2, q22) = points

 

    # if x1 != _x1 or x2 != _x2 or y1 != _y1 or y2 != _y2:

 

    #     raise ValueError('points do not form a rectangle')

 

    # if not x1 <= x <= x2 or not y1 <= y <= y2:

 

    #     raise ValueError('(x, y) not within the rectangle')

 

    if x1 == x2 and _x1 == _x2 and x1 == _x1:

 

        y_top = max(q11, q12, q21, q22)

 

        y_bot = min(q11, q12, q21, q22)

 

        return (y_top - y_bot) / 100 * Heat_Recovery + y_bot

 

    if y1 == y2 and _y1 == _y2 and y1 == _y1:

 

        x_top = max(q11, q12, q21, q22)

 

        x_bot = min(q11, q12, q21, q22)

 

        return (x_top - x_bot) / 100 * Fan_Power + x_bot

 

    return (q11 * (x2 - Fan_Power) * (y2 - Heat_Recovery) +

 

            q21 * (Fan_Power - x1) * (y2 - Heat_Recovery) +

 

           q12 * (x2 - Fan_Power) * (Heat_Recovery - y1) +

 

            q22 * (Fan_Power - x1) * (Heat_Recovery - y1)

 

            ) / ((x2 - x1) * (y2 - y1) + 0.0)

 


 

def calc_energy_use(df):

 

    '''

 

    :param df: pandas DataFrame     Dataframe mit zumindest den folgenden Spalten:

 

                                    Fan_Power:          float   Zuluftventilatorleistung in %

 

                                    Heat_Recovery:      float   Wärmerückgewinnungsklappenstellung in %

 

                                    #####SEC_Air_Damper:     float   Umluftklappenstellung in % [nur fuer Frischluftanteil benötigt]

 

                                    Inlet_Temperature:  float   Temperatur der Zuluft hinterm Heizregister

 

                                    Mixed_Temperature:  float   Temperatur der Zuluft vor dem Heizregister

 

    :return:   pandas DataFrame     Eingangs-DataFrame mit zwei zusätzlichen Spalten:

 

                                    Volume_Flow:        float   Luftvolumenstrom Lufteinlass in m³/h

 

                                    Energy_Flow:        float   Kühl-/Heizleistung des Kühl-/Heizregisters in kW

 

    '''

 

    try:

 

        df['Volume_Flow'] = df.apply(lambda row: bilinear_interpolation(row['Fan_Power'], row['Heat_Recovery']), axis=1)

 

        #df['Fresh_Air_Flow'] = df.apply(lambda row: V_i_cond(row['SEC_Air_Damper'],

 

        #                                                     row['Heat_Recovery'],

 

        #                                                     row['Fan_Power']), axis=1)

 

                            # Volume_Flow [m³/h] * rho_L [kg/m³] * h/s * (T_out-T_in) [K] * cp_L [KJ/kg*K]

 

        df['Energy_Flow'] = df.apply(lambda row: row['Volume_Flow'] * 1.2041/3600 *

 

                                                 (row['Inlet_Temperature'] - row['Mixed_Temperature']) * 1.01, axis=1)

 

        return df

 

    except:

 

        df['Volume_Flow'] = NaN

 

        df['Energy_Flow'] = NaN

 

        return df
0 Answers
Related