Skip to main content
 首页 » 编程设计

python之NumPy 与 MATLAB

2025年05月04日15sxdcgaq8080

我已经开始在很多事情上使用 NumPy 而不是 MATLAB,而且对于大多数事情来说,它似乎要快得多。我刚刚尝试在 Python 中复制代码,但速度要慢得多。我想知道两者都知道的人是否可以看看它,看看为什么会这样

数字货币:

longTicker = np.empty([1,len(ticker)],dtype='U15') 
genericTicker = np.empty([len(ticker)],dtype='U15') 
tickerType = np.empty([len(ticker)],dtype='U10') 
tickerList = np.vstack((np.empty([2,len(ticker)],dtype='U30'),np.ones([len(ticker)],dtype='U30'))) 
tickerListnum = 0 
modelList = np.empty([2,9999],dtype='U2') 
modelListnum = 0 
derivativeType = np.ones(len(ticker)) 
 
for l in range(0,len(ticker)): 
    tickerType[l] = 'Future' 
 
    if not modCode[l] in list(modelList[1,:]): 
        modelList[0,modelListnum] = modelListnum + 1 
        modelList[1,modelListnum] = modCode[l] 
        modelListnum += 1 
 
    if ticker.item(l).find('3 MONTH') >= 0: 
        x = list(metalTicks[:,0]).index(ticker[l]) 
        longTicker[0,l]  = metalTicks[x,3] 
        if not longTicker[0,l] in list(tickerList[1,:]): 
            tickerList[0,tickerListnum] = tickerListnum + 1 
            tickerList[1,tickerListnum] = longTicker[0,l]  
            tickerList[2,tickerListnum] = 4 
            tickerListnum += 1 
 
        derivativeType[l] = 4 
        tickerType[l] = 'Future' 
 
    if ticker.item(l).find('CURNCY') >= 0: 
        if ticker.item(l).find('KRWUSD CURNCY'): 
            prices[l] = 1/float(prices.item(l)) 
 
        longTicker[0,l]  = ticker[l,0] 
        if not longTicker[0,l] in list(tickerList[1,:]): 
            tickerList[0,tickerListnum] = tickerListnum + 1 
            tickerList[1,tickerListnum] = longTicker[0,l]  
            tickerList[2,tickerListnum] = 2 
            tickerListnum += 1 
 
        derivativeType[l] = 2 
        tickerType[l] = 'FX'     
 
    if ticker.item(l).find('_') >= 0: 
        x = ticker[l] == sasTick 
        longTicker[0,l]  = bbgTick[x] 
        if not longTicker[0,l] in list(tickerList[1,:]): 
            tickerList[0,tickerListnum] = tickerListnum + 1 
            tickerList[1,tickerListnum] = longTicker[0,l]  
            tickerList[2,tickerListnum] = 3 
            tickerListnum += 1 
 
        derivativeType[l] = 3 
        tickerType[l] = 'Option' 
 
    # need convert ticker thing     
 
    if not longTicker[0,l] in list(tickerList[1,:]): 
            tickerList[0,tickerListnum] = tickerListnum + 1 
            tickerList[1,tickerListnum] = longTicker[0,l]  
            tickerList[2,tickerListnum] = 1 
            tickerListnum += 1 

MATLAB 代码:
longTicker = cell(size(ticker)); 
genericTicker = cell(size(ticker)); 
type = repmat({'Future'},size(ticker)); 
tickerList = repmat([cell(1);cell(1);{1}],1,9999); 
%tickerList = cell(3,9999); 
tickerListnum = 0; 
modelList = cell(2,9999); 
modelListnum = 0; 
derivativeType = ones(size(ticker)); 
 
for j=1:length(ticker) 
 
    if isempty(find(strcmp(modCode{j},modelList(2,:)), 1)) 
        modelListnum = modelListnum+1; 
        modelList{1,modelListnum}= modelListnum; 
        modelList(2,modelListnum)= modCode(j); 
    end 
 
    if ~isempty(strfind(ticker{j},'3 MONTH')) 
        x =strcmp(ticker{j},metalTicks(:,1)); 
        longTicker{j} = metalTicks{x,4}; 
        % genericTicker{j} = metalTicks{x,4}; 
        if isempty(find(strcmp(longTicker(j),tickerList(2,:)), 1)) 
        tickerListnum = tickerListnum+1; 
        tickerList{1,tickerListnum}= tickerListnum; 
        tickerList(2,tickerListnum)=longTicker(j); 
        tickerList{3,tickerListnum}=4; 
        end 
        derivativeType(j) = 4; 
        type{j} = 'Future'; 
        continue; 
    end 
    if ~isempty(regexp(ticker{j},'[A-Z]{6}\sCURNCY', 'once')) 
        if strcmpi('KRWUSD CURNCY',ticker{j}) 
            prices{j}=1/prices{j}; 
        end 
        longTicker{j} = ticker{j}; 
        % genericTicker{j} = ticker{j}; 
        if isempty(find(strcmp(longTicker(j),tickerList(2,:)), 1)) 
        tickerListnum = tickerListnum+1; 
        tickerList{1,tickerListnum}= tickerListnum; 
        tickerList(2,tickerListnum)=longTicker(j); 
        tickerList{3,tickerListnum}=2; 
        end 
        derivativeType(j) = 2; 
        type{j} = 'FX'; 
        continue; 
    end 
    if ~isempty(regexp(ticker{j},'_', 'once')) 
        z = strcmp(ticker{j},sasTick); 
        try 
            longTicker(j) = bbgTick(z); 
        catch 
            keyboard;  % I did this - Dave 
        end 
        % genericTicker(j) = bbgTick(z); 
        if isempty(find(strcmp(longTicker(j),tickerList(2,:)), 1)) 
        tickerListnum = tickerListnum+1; 
        tickerList{1,tickerListnum}= tickerListnum; 
        tickerList(2,tickerListnum)=longTicker(j); 
        tickerList{3,tickerListnum}=3; 
        end 
        derivativeType(j) = 3; 
        type{j} = 'Option'; 
        continue; 
    end 
    try 
        longTicker{j} = ConvertTicker(ticker{j},'short','long',tradeDate(j)); 
        % genericTicker{j} = ConvertTicker(ticker{j},'short','generic',tradeDate(j)); 
    catch 
        longTicker{j} = ticker{j}; 
        % genericTicker{j} = ticker{j}; 
    end 
    if isempty(find(strcmp(longTicker(j),tickerList(2,:)), 1)) 
        tickerListnum = tickerListnum+1; 
        tickerList{1,tickerListnum}= tickerListnum; 
        tickerList(2,tickerListnum)=longTicker(j); 
        tickerList{3,tickerListnum}=1; 
    end 
end 

在这种情况下,MATLAB 似乎快了大约 100 倍。 Python中的循环慢得多吗?

请您参考如下方法:

虽然我不能确定减速的主要原因是什么,但我确实注意到一些会导致减速的事情,很容易修复,并且会产生更清晰的代码:

  • 你做了很多从 numpy 数组到列表的转换。类型转换很昂贵,尽可能避免使用它们。在你的情况下,你从 numpy 中获益很少。在几乎所有情况下,最好只使用列表代替一维数组或列表列表代替二维数组。这更接近 MATLAB 中的元胞数组,只是它们可以动态调整大小并具有良好的性能。唯一可能的异常(exception)是 sastick , bbgtick , 和 prices ,后两者都可以正常工作。对于其他人,如果您只是增量放置值,只需创建空列表并使用 append ,并且对于需要使用 None 预分配访问任意元素的情况或空字符串 '' .对于 tickerList有两个列表可能更容易。
  • 您将大量整数分配给 unicode 数组。这还涉及类型转换(整数到 unicode)。如果您使用列表,这也不会成为问题。
  • 您使用 foo.item(l)很多。这会将 numpy 元素转换为普通的 python 数据类型。同样,这是一种类型转换,所以如果可以避免,请不要这样做。如果你听从我的建议 1并使用列表,您永远不需要在当前代码中执行此操作。
  • 你有 continue MATLAB 版本中的语句而不是 python 版本中的语句,这意味着您正在 Python 版本中进行计算,而您在 MATLAB 版本中跳过了这些语句。我认为您最好使用 if..elseif , 但是 continue也适用于 Python。
  • 你循环了range(0,len(ticker)) ,然后多次提取ticker的那个元素。你最好只循环 ticker直接,通过做,例如for i, iticker in enumerate(ticker): .使用 enumerate还允许您跟踪索引。
  • 您使用 find确定子字符串是否在给定字符串中。使用 in 更快、更清晰、更简单为了那个原因。仅使用 find如果您确切地关心找到子字符串的位置,那么您不关心。
  • 对于modelListnum和 tickerListnum ,您加一,将值分配给数组元素,然后加一并将其分配回自身,两次执行相同的操作。在 MATLAB 版本中,您首先递增,然后分配已经递增的版本。这涉及在 Python 中执行相同数学运算的频率是在 MATLAB 中的两倍。
  • 预分配tickerType更快像你在 MATLAB 中那样去“ future ”,你可以通过使用类似 tickerType = ['Future']*len(ticker) 的东西来做到这一点.
  • 由于tickerListnum和 modelListnum总是等于索引,根本没有理由拥有那些。只是摆脱他们。
  • 因为在 tickerList 的第一行中每个值只有一个实例。 ,使用 OrderedDict 会更快更容易, 或常规 dict如果你不关心顺序,这里的键是 longTicker value 和 value 是类型号。
  • 如果不关心 modelList 的顺序, 使用 set会更快。

  • 所以这里有一个应该更快的版本,假设 metalTicks , 和 tickerList是列表列表, sasTick是一个 numpy 数组,并且 prices和 bbgTick是列表或数组,假设您关心 modelList 的顺序和 tickerList :
    from collections import OrderedDict 
     
    longTicker = [None]*len(ticker) 
    tickerType = ['Future']*len(ticker) 
    tickerList = OrderedDict() 
    modelList = [] 
    derivativeType = np.ones_like(ticker) 
     
    for i, (iticker, imodCode)  in enumerate(zip(ticker, modCode)): 
        if imodCode not in modelList: 
            modelList.append(imodCode) 
     
        if '3 MONTH' in iticker: 
            x = metalTicks[0].index(iticker) 
            longTicker[i] = metalTicks[3][x] 
            derivativeType[i] = 4 
     
        elif 'CURNCY' in iticker: 
            if 'KRWUSD CURNCY' in iticker: 
                prices[i] = 1/prices[i] 
     
            longTicker[i]  = iticker 
            derivativeType[i] = 2 
            tickerType[i] = 'FX'     
     
        elif '_' in iticker: 
            longTicker[i]  = bbgTick[iticker == sasTick] 
            derivativeType[i] = 3 
            tickerType[i] = 'Option' 
     
        tickerList[longTicker[i]] = derivativeType[i] 
    

    如果不关心 modelList 的顺序和 tickerList , 你可以这样做:
    longTicker = [None]*len(ticker) 
    tickerType = ['Future']*len(ticker) 
    tickerList = {} 
    modelList = set() 
    derivativeType = np.ones_like(ticker) 
     
    for i, (iticker, imodCode)  in enumerate(zip(ticker, modCode)): 
        modelList.add(imodCode) 
     
        if '3 MONTH' in iticker: 
            x = metalTicks[0].index(iticker) 
            longTicker[i] = metalTicks[3][x] 
            derivativeType[i] = 4 
     
        elif 'CURNCY' in iticker: 
            if 'KRWUSD CURNCY' in iticker: 
                prices[i] = 1/prices[i] 
     
            longTicker[i]  = iticker 
            derivativeType[i] = 2 
            tickerType[i] = 'FX'     
     
        elif '_' in iticker: 
            longTicker[i]  = bbgTick[iticker == sasTick] 
            derivativeType[i] = 3 
            tickerType[i] = 'Option' 
     
        tickerList[longTicker[i]] = derivativeType[i] 
    

    或者更简单:
    longTicker = [None]*len(ticker) 
    tickerType = ['Future']*len(ticker) 
    derivativeType = np.ones_like(ticker) 
     
    for i, iticker in enumerate(ticker): 
        if '3 MONTH' in iticker: 
            x = metalTicks[0].index(iticker) 
            longTicker[i] = metalTicks[3][x] 
            derivativeType[i] = 4 
     
        elif 'CURNCY' in iticker: 
            if 'KRWUSD CURNCY' in iticker: 
                prices[i] = 1/prices[i] 
     
            longTicker[i]  = iticker 
            derivativeType[i] = 2 
            tickerType[i] = 'FX' 
     
        elif '_' in iticker: 
            longTicker[i]  = bbgTick[iticker == sasTick] 
            derivativeType[i] = 3 
            tickerType[i] = 'Option' 
     
    modelList = set(modCode) 
    tickerlist = dict(zip(longTicker, derivativeType))