NumPy与MATLAB

时间:2015-06-10 08:15:44

标签: python matlab numpy

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

NumPy的:

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代码:

{{1}}

在这种情况下,MATLAB的速度提高了大约100倍。 Python中的循环要慢得多吗?

1 个答案:

答案 0 :(得分:6)

虽然我无法确定减速的主要来源是什么,但我注意到一些会导致速度减慢,易于修复并且会导致代码更清晰的事情:

  1. 你做了很多从numpy数组到列表的转换。类型转换很昂贵,尽量避免使用它们。在你的情况下,你很少从numpy中受益。在几乎所有情况下,最好只使用列表代替一维数组或列表列表代替二维数组。这更接近MATLAB中的单元阵列,除了它们可以动态调整大小并具有良好的性能。唯一可能的例外是sastickbbgtickprices,后两种工作正常。对于其他人,如果您只是以增量方式放置值,只需创建空列表并使用append,以及需要访问使用None预分配的任意元素或空字符串{{ 1}}。对于'',可能更容易有两个列表。
  2. 您为unicode数组分配了很多整数。这还涉及类型转换(整数到unicode)。如果您使用列表,这也不会成为问题。
  3. 您经常使用tickerList。这会将numpy元素转换为普通的python数据类型。同样,这是一种类型转换,所以如果可以避免,请不要这样做。如果您按照我的建议foo.item(l)并使用列表,则无需在当前代码中执行此操作。
  4. 您在MATLAB版本中有1个语句,但在python版本中没有,这意味着您正在使用MATLAB版本中跳过的Python版本进行计算。我认为你最好使用continue,但if..elseif也适用于Python。
  5. 循环遍历continue,然后多次提取该代码元素。您最好直接循环range(0,len(ticker)),例如ticker。使用for i, iticker in enumerate(ticker):还可以跟踪索引。
  6. 使用enumerate确定子字符串是否在给定字符串中。只需使用find就可以更快,更清晰,更简单。如果您确切地关注找到子字符串的位置,请仅使用in
  7. 对于findmodelListnum,您添加一个,将值分配给数组元素,然后添加一个并将其分配回自身,执行相同的操作两次。在MATLAB版本中,首先递增,然后分配已经递增的版本。这涉及在Python中使用相同的数学运算两倍,就像在MATLAB中一样。
  8. tickerListnum预分配给未来'会更快。就像你在MATLAB中所做的那样,你可以使用tickerType
  9. 之类的东西
  10. 由于tickerType = ['Future']*len(ticker)tickerListnum始终等于索引,因此没有理由拥有这些索引。摆脱它们。
  11. 由于modelListnum的第一行中每个值只有一个实例,因此使用tickerList或常规OrderedDict会更快更容易#39; t关心订单,其中键是dict值,值是类型编号。
  12. 如果您不关心longTicker的顺序,使用modelList会更快。
  13. 所以这里的版本应该更快,假设setmetalTicks是列表列表,tickerList是一个numpy数组,sasTick和{{ 1}}是列表或数组,假设您关心pricesbbgTick的oder:

    modelList

    如果您不关心tickerListfrom 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