2016-07-19 5 views
2

Я вижу, что есть array_split и splitmethods, но это не очень удобно, когда вам нужно разделить массив длины, который не является целым числом, кратным размеру куска. Более того, ввод этих методов - это количество срезов, а не размер среза. Мне нужно что-то более похожее на метод Matlab buffer, который более подходит для обработки сигналов.Есть ли эквивалент буфера Matlab в numpy?

Например, если я хочу буферизовать сигналы на куски размером 60, мне нужно сделать: np.vstack(np.hsplit(x.iloc[0:((len(x)//60)*60)], len(x)//60)), что является громоздким.

+1

Вы попробовали 'np.split'? Он разбивается на указанные индексы, поэтому должен заботиться о нерегулярных интервалах. Нам просто нужно создать эти индексы, используя диапазон. – Divakar

+0

Или, может быть, это помогает https://mail.scipy.org/pipermail/scipy-user/2006-November/009962.html и код на https://mail.scipy.org/pipermail/scipy-user/attachments/ 20061119/292f81e3/attachment.py –

+1

Быстрый взгляд на документ 'buffer' напоминает мне« numpy'' stride_tricks.as_strided », особенно в его способности перекрывать и пропускать обработчик. Но это может быть слишком сильным и опасным для этого случая. – hpaulj

ответ

3

Я написал следующую процедуру для обработки необходимых мне прецедентов, но я не реализовал/не протестировал ее для «underlap».

Пожалуйста, не стесняйтесь делать предложения по улучшению.

def buffer(x, n, p=0, opt=None): 
    '''Mimic MATLAB routine to generate buffer array 

    MATLAB docs here: https://se.mathworks.com/help/signal/ref/buffer.html 

    Args 
    ---- 
    x: signal array 
    n: number of data segments 
    p: number of values to overlap 
    opt: initial condition options. default sets the first `p` values 
     to zero, while 'nodelay' begins filling the buffer immediately. 
    ''' 
    import numpy 

    if p >= n: 
     raise ValueError('p ({}) must be less than n ({}).'.format(p,n)) 

    # Calculate number of columns of buffer array 
    cols = int(numpy.ceil(len(x)/float(n-p))) 

    # Check for opt parameters 
    if opt == 'nodelay': 
     # Need extra column to handle additional values left 
     cols += 1 
    elif opt != None: 
     raise SystemError('Only `None` (default initial condition) and ' 
          '`nodelay` (skip initial condition) have been ' 
          'implemented') 

    # Create empty buffer array 
    b = numpy.zeros((n, cols)) 

    # Fill buffer by column handling for initial condition and overlap 
    j = 0 
    for i in range(cols): 
     # Set first column to n values from x, move to next iteration 
     if i == 0 and opt == 'nodelay': 
      b[0:n,i] = x[0:n] 
      continue 
     # set first values of row to last p values 
     elif i != 0 and p != 0: 
      b[:p, i] = b[-p:, i-1] 
     # If initial condition, set p elements in buffer array to zero 
     else: 
      b[:p, i] = 0 

     # Get stop index positions for x 
     k = j + n - p 

     # Get stop index position for b, matching number sliced from x 
     n_end = p+len(x[j:k]) 

     # Assign values to buffer array from x 
     b[p:n_end,i] = x[j:k] 

     # Update start index location for next iteration of x 
     j = k 

    return b 
+1

Работал для меня с одной незначительной настройкой. Поскольку я использую Python 3 (моя теория), переменная «cols» была усечена. Думайте, это связано с изменением того, как Python 3 занимается умножением. Я запустил знаменатель в уравнение вычисления «cols», а результат затем соответствовал выход Matlab точно в моем случае. 'cols = int (np.ceil (len (x)/float ((n-p))))' – user2348114

+0

Спасибо. Я тоже использую Python 3, но я не использовал это, поэтому, возможно, я этого не заметил. – ryanjdillon

Смежные вопросы