Search code examples
pythonpandasdataframesympyintegral

Is it possible to make derived variables from pandas Dataframe with sympy Integral?


My Problem

Hello! Is it possible to use pandas DataFrame with sympy package?

I seek method for making derived column(variable) from pandas Dataframe with sympy Integral.

But I encountered some problem with those process.

How can I solve this problem?

My Code

  • I tried to make derived variable from some columns.
  • df means pandas DataFrame.
  • 'a', 'T_c', 'lambda_t' et al are variables(columns) of pandas DataFrame.
from sympy import *
import pandas as pd
import numpy as np

df = pd.read_csv('https://raw.githubusercontent.com/regenesis90/datasets/master/210521_LSJ_test.csv', encoding = 'cp949')
df

enter image description here


t = Symbol('t')

df['l_star'] = 100 
df['a_i_n'] = 0 
df['b_i_n'] = 0 
df['c_i_n'] = 0

df['L']= df['l'] + df['l_star']
df['Q_rt'] = df['Q_r'] - df['Q_w2']
df['Q_t'] = df['Q_m'] - df['Q_w1']

df['Q'] = df['Q_m'] + df['Q_r']

df['S_r_merging'] = (df['V_m']**2 - df['V_r']**2)/(2 * df['Acc'])

df['t_hat_m'] = 3600/(df['Q_m'] + df['Q_w2'] * (1 - (df['Q_w1']/df['Q_m'])))
df['t_hat_r'] = 3600/(df['Q_r'] + df['Q_w1'] * (1 - (df['Q_w2']/df['Q_r'])))
df['t_hat'] = 3600/df['Q']

df['lambda_m'] = df['K']/(df['t_hat_m'] - df['a'])
df['lambda_r'] = df['K']/(df['t_hat_r'] - df['a'])
df['lambda_t'] = df['K']/(df['t_hat'] - df['a'])


df['func_integ_tf_01'] = t * df['lambda_t']**2 * (t - df['a']) * np.exp(-df['lambda_t']) * np.exp(- df['a']) * exp(t)
df['integ_tf_01'] = Integral(df['func_integ_tf_01'], (t, df['a'], df['T_c'])).doit()

Error

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-107-6e7da2479649> in <module>
      1 df['func_integ_tf_01'] = t * df['lambda_t']**2 * (t - df['a']) * np.exp(-df['lambda_t']) * np.exp(- df['a']) * exp(t)
----> 2 df['integ_tf_01'] = Integral(df['func_integ_tf_01'], (t, df['a'], df['T_c'])).doit()

C:\dev\Anaconda3\lib\site-packages\sympy\integrals\integrals.py in __new__(cls, function, *symbols, **assumptions)
     85                 useinstead="the as_expr or integrate methods of Poly").warn()
     86 
---> 87         obj = AddWithLimits.__new__(cls, function, *symbols, **assumptions)
     88         return obj
     89 

C:\dev\Anaconda3\lib\site-packages\sympy\concrete\expr_with_limits.py in __new__(cls, function, *symbols, **assumptions)
    492 
    493     def __new__(cls, function, *symbols, **assumptions):
--> 494         pre = _common_new(cls, function, *symbols, **assumptions)
    495         if type(pre) is tuple:
    496             function, limits, orientation = pre

C:\dev\Anaconda3\lib\site-packages\sympy\concrete\expr_with_limits.py in _common_new(cls, function, *symbols, **assumptions)
     46 
     47     if symbols:
---> 48         limits, orientation = _process_limits(*symbols)
     49         for i, li in enumerate(limits):
     50             if len(li) == 4:

C:\dev\Anaconda3\lib\site-packages\sympy\concrete\expr_with_limits.py in _process_limits(*symbols)
    154                         continue
    155 
--> 156         raise ValueError('Invalid limits given: %s' % str(symbols))
    157 
    158     return limits, orientation

**ValueError: Invalid limits given: ((t, 0    1
1    1
2    1
3    1
4    1
Name: a, dtype: int64, 0    3
1    3
2    3
3    3
4    3
Name: T_c, dtype: int64),)**

Solution

  • Integral cannot be applied over an array. You have to call this function over each row of your dataframe, so you need a loop. In pandas, use apply method to iterate along an axis and apply a function. In your case axis is rows, so pass axis=columns to iterate over rows.

    I suppose you want something like this:

    df['integ_tf_01'] = df.apply(lambda sr: Integral(sr['func_integ_tf_01'], (t, sr['a'], sr['T_c'])).doit(), axis="columns")
    
    >>> df['integ_tf_01']
    0    -0.118858683067447*E + 0.35657604920234*exp(3)
    1    -0.118858683067447*E + 0.35657604920234*exp(3)
    2    -0.118858683067447*E + 0.35657604920234*exp(3)
    3    -0.118858683067447*E + 0.35657604920234*exp(3)
    4    -0.118858683067447*E + 0.35657604920234*exp(3)
    Name: integ_tf_01, dtype: object