如何使用eval dataframe方法在自定义函数中返回numpy数组或列表?

时间:2017-11-07 16:55:13

标签: python python-3.x pandas dataframe eval

我正在使用python 3.X.我正在尝试使用eval()数据框方法,包括像这样的自定义函数

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'T': [0, 10, 0, 10, 10, 30],
    'P': [0, 0, 1000, 1000, 0, 0],
    'S': [25, 25, 25, 25, 40, 40]
})

def custom(A, B, C):
    # some operations

    aux = pd.DataFrame({
        'A': [0, 10, 0, 10, 10, 30],
    })
    return aux.A      # here is where I want to return the numpy array or list, or dataframe column

eq = 'RES = T + @custom(S, T, P) + 2'
df.eval(eq, engine='numexpr', inplace=True)

但是我只能在函数中返回一个浮点值或整数值,这是一个简单的值。

所以我想返回一个numpy数组或一个值列表,因为我想使用结果来处理其余的方程变量。我收到这个错误:

TypeError: unhashable type: 'numpy.ndarray'

另一个例子:

import pandas as pd
import numpy as np
import seawater as sw
from seawater.library import T90conv

df = pd.DataFrame({
    'T': T90conv([0, 10, 0, 10, 10, 30]),
    'P': [0, 0, 1000, 1000, 0, 0],
    'S': [25, 25, 25, 25, 40, 40]
})

cndr = sw.cndr                  # it returns a numpy array
eq = 'NEW = @cndr(S, T, P)'
df.eval(eq, engine='numexpr', inplace=True)

这可能吗?我可以返回什么类型?还有另一种方法可以达到这个目的吗?

1 个答案:

答案 0 :(得分:1)

我无法使用numexpr引擎使其工作 - 它总是给我TypeError: unhashable type: 'numpy.ndarray'

我还尝试将numpy.ndarray转换为listtuple - 它仍然说:TypeError: unsupported expression type: <class 'tuple'>TypeError: unhashable type: 'list'

但它适用于python引擎:

In [47]: df.eval("NEW = @sw.cndr(S, T, P)", engine='python', inplace=True)

In [48]: df
Out[48]:
      P   S          T       NEW
0     0  25   0.000000  0.498008
1     0  25   9.997601  0.654990
2  1000  25   0.000000  0.506244
3  1000  25   9.997601  0.662975
4     0  40   9.997601  1.000073
5     0  40  29.992802  1.529967

以下解决方法如何?

In [77]: df = df.assign(RES=sw.cndr(df['S'], df['T'], df['P'])) \
                .eval("RES = T + RES + 2", inplace=False)

In [78]: df
Out[78]:
      P   S          T        RES
0     0  25   0.000000   2.498008
1     0  25   9.997601  12.652591
2  1000  25   0.000000   2.506244
3  1000  25   9.997601  12.660576
4     0  40   9.997601  12.997674
5     0  40  29.992802  33.522769