Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何根据不同的输入大小优化代码?_Python_Python 3.x_Performance_Optimization - Fatal编程技术网

Python 如何根据不同的输入大小优化代码?

Python 如何根据不同的输入大小优化代码?,python,python-3.x,performance,optimization,Python,Python 3.x,Performance,Optimization,我想以最有效的方式计算蒸汽属性,将标量、向量和矩阵作为两个参数输入选项。我所担心的是,我必须根据输入的大小(标量、向量或矩阵)使用if块,这使得代码相当长。我是一名简单的机械工程师,对python非常陌生,非常感谢任何关于如何优化代码的帮助。代码如下: from iapws.iapws97 import _Region4 import numpy as np def h_x(P,x): ''' spec enthalpy in liquid, steam and wet (two-p

我想以最有效的方式计算蒸汽属性,将标量、向量和矩阵作为两个参数输入选项。我所担心的是,我必须根据输入的大小(标量、向量或矩阵)使用if块,这使得代码相当长。我是一名简单的机械工程师,对python非常陌生,非常感谢任何关于如何优化代码的帮助。代码如下:

from iapws.iapws97 import _Region4
import numpy as np

def h_x(P,x): 
    ''' spec enthalpy in liquid, steam and wet (two-phase flow) regions
    P - pressure in bar
    x - drayness steam fraction [-]
    h - specific heat of wet region returned [kJ/kW]
    '''

    mm = len(np.shape(x))
    if mm == 0:
        h_  = _Region4(P/10,0)['h'] 
        h__ = _Region4(P/10,1)['h'] 
        # return h_ + x * (h__ - h_)
        return h_ + x * (h__ - h_)        
    elif mm == 1:
        return np.array([ _Region4(i/10,0)['h'] + j * ( _Region4(i/10,1)['h'] - _Region4(i/10,0)['h'] ) for i,j in zip(P,x) ])    
    elif mm == 2:
        mmm,nnn = x.shape
        h     = np.ndarray(shape=(mmm,nnn)) #(mm,nn)
        for i in range(mmm):
            for j in range(nnn):
                h_  = _Region4(P[i,j]/10,0)['h']
                h__ = _Region4(P[i,j]/10,1)['h']
                h[i,j]   = h_ + x[i,j] * (h__ - h_)
        return h        
    else:
        print('h_x input must be scalar, vector or 2D matrix!')

# code testing
P = np.array([[.0234,.0193,0.244],[.0244,.0185,0.254]])
x = np.array([[.812,.782,.620],[.912,.882,.820]])
h_x(P,x)

实际上,您只进行一次计算,但有两种不同的方式。您可以使用内置的
映射
将其拉出并应用于函数作为输入的任何内容。如果失败,那么您就有一个(不可iterable)值,并直接应用您的计算

# Define a dummy func to make code work
def _Region4(a, b):
    return {'h': a + 3 * b}

import numpy as np

def calculate(P, x):
    '''
    Spec enthalpy in liquid, steam and wet (two-phase flow) regions
    P - pressure in bar
    x - drayness steam fraction [-]
    h - specific heat of wet region returned [kJ/kW]
    '''
    h_  = _Region4(P/10,0)['h'] 
    h__ = _Region4(P/10,1)['h'] 
    return h_ + x * (h__ - h_) 

def h_x(P,x):
    shape = np.shape(x)
    dimensions = len(shape)
    # Check for wrong input
    if dimensions > 2:
        raise ValueError('h_x input must be scalar, vector or 2D matrix!')
    # Try a general mapping
    try:
        return np.array(list(map(calculate, P.flat, x.flat))).reshape(shape)
    # if it fails then you got a pair of scalar
    except AttributeError:
        return calculate(P, x)

P = np.array([[.023,.23,.05],[.023,.23,.05]])
x = np.array([[.92,.98,.99],[.92,.98,.99]])
print(h_x(P, x))
"""
Out:
    [[2.7623 2.963  2.975 ]
    [2.7623 2.963  2.975 ]]
"""
print(h_x(3, 4))
"""
Out:
    12.3
"""

我不知道效率,但代码方面。。。我会把所有东西都变换成二维矩阵。。。千计算代码将是一个单独的块<代码>标量->[[scalar]],[scalar1,scalar1]->[[scalar1,scalar1]]]谢谢你,正在玩你的代码。如果输入是标量和向量,例如P=np.array([.023,.23,.05])x=np.array([.92,.98,.99]),代码可以很好地计算输出,没有错误。如果输入是矩阵,例如P=np array([.023,.23,.05],.023,.23,.05]))x=np.array([.92.98.99]、[.92.98.99]))它抛出错误:ValueError:包含多个元素的数组的真值不明确。请使用a.any()或a.all()这与我在I和j上的两个for循环中避免的错误相同,最终使代码相当长。也许还有其他想法吗?谢谢。我找到了numpy变量的.flat属性。因此这很好地工作了:mm,nn=P.shape hh=np.array(list(map(calculate,P.flat,x.flat))#。flat变量迭代所有数组元素hh=np.reformate(hh,(mm,nn))我想我已经弄明白了。似乎可以将标量、向量和矩阵压缩成一行,即np.数组(list(map(calculate,P.flat,x.flat)))。重塑(P.shape),其中.flat将输入展平,然后。重塑(P.shape)对输入参数产生相同的结果。重要的是参数(P,x)定义为np.array()。在本例中,标量也具有iter属性,并且被map()接受,因此没有len(np.shape(x)),然后是np.reformate()线是需要的。对我来说,它可以与2D数组配合使用,无需展平和重塑。我将添加我正在使用的完整代码供您查看。我理解为什么它会对您造成中断,您使用展平的解决方案是正确的。我对_区域4使用虚拟方法,但您对数据做了其他操作,它会中断。更新了答案中的代码有了这些信息,它应该会起作用。