Есть ли в Python функция, которая может выполнять обратную функцию numpy.repeat?

Например

x = np.repeat(np.array([[1,2],[3,4]]), 2, axis=1)

дает вам

x = array([[1, 1, 2, 2],
          [3, 3, 4, 4]])

но есть ли что-то, что может выполнить

 x = np.*inverse_repeat*(np.array([[1, 1, 2, 2],[3, 3, 4, 4]]), axis=1)

и дает вам

x = array([[1,2],[3,4]])
7 голосов | спросил Soumya Shubhra Ghosh 2 PM00000040000003231 2016, 16:38:32

4 ответа


0

Регулярная нарезка должна работать. Для оси, которую вы хотите инвертировать , используйте ::number_of_repetitions

x = np.repeat(np.array([[1,2],[3,4]]), 4, axis=0)
x[::4, :]  # axis=0
Out: 
array([[1, 2],
       [3, 4]])

x = np.repeat(np.array([[1,2],[3,4]]), 3, axis=1)

x[:,::3]  # axis=1
Out: 
array([[1, 2],
       [3, 4]])


x = np.repeat(np.array([[[1],[2]],[[3],[4]]]), 5, axis=2)
x[:,:,::5]  # axis=2
Out: 
array([[[1],
        [2]],

       [[3],
        [4]]])
ответил ayhan 2 PM00000040000000931 2016, 16:46:09
0

Это должно работать и иметь такую ​​же подпись, как np.repeat:

def inverse_repeat(a, repeats, axis):
    if isinstance(repeats, int):
        indices = np.arange(a.shape[axis] / repeats, dtype=np.int) * repeats
    else:  # assume array_like of int
        indices = np.cumsum(repeats) - 1
    return a.take(indices, axis)

Редактировать: добавлена ​​поддержка повторений для каждого элемента, аналогично np.repeat

ответил Eelco Hoogendoorn 2 PM00000040000005931 2016, 16:55:59
0

Для случая, когда мы знаем ось и повтор - а повтор - это скаляр (одинаковое значение для всех элементов), мы можем построить индекс среза следующим образом:

In [1117]: a=np.array([[1, 1, 2, 2],[3, 3, 4, 4]])
In [1118]: axis=1; repeats=2

In [1119]: ind=[slice(None)]*a.ndim
In [1120]: ind[axis]=slice(None,None,a.shape[axis]//repeats)
In [1121]: ind
Out[1121]: [slice(None, None, None), slice(None, None, 2)]
In [1122]: a[ind]
Out[1122]: 
array([[1, 2],
       [3, 4]])

@Eelco's использование take делает проще сфокусироваться на одной оси, но требуется список индексов, а не срез.

Но repeat допускает различное количество повторений.

In [1127]: np.repeat(a1,[2,3],axis=1)
Out[1127]: 
array([[1, 1, 2, 2, 2],
       [3, 3, 4, 4, 4]])

Зная axis=1 и repeats=[2,3] мы должна быть в состоянии создать правильное индексирование take (возможно, с помощью cumsum). Нарезка не будет работать.

Но если мы знаем только ось, а повторы неизвестны, то нам, вероятно, понадобится какой-то unique или set, как в @redratear's.

In [1128]: a2=np.repeat(a1,[2,3],axis=1)
In [1129]: y=[list(set(c)) for c in a2]
In [1130]: y
Out[1130]: [[1, 2], [3, 4]]

A take решение со списком repeats. Это должно выбрать последний из каждого повторного блока:

In [1132]: np.take(a2,np.cumsum([2,3])-1,axis=1)
Out[1132]: 
array([[1, 2],
       [3, 4]])

Удаленный ответ использует unique; вот мое построчное использование unique

In [1136]: np.array([np.unique(row) for row in a2])
Out[1136]: 
array([[1, 2],
       [3, 4]])

unique лучше, чем set для этого использования, поскольку он поддерживает порядок элементов. Есть еще одна проблема с unique (или установлен) - что, если оригинал имел повторяющиеся значения, например [[1,2,1,3],[3,3,4,1]]

Вот случай, когда было бы трудно вывести шаблон повторения из результата. Я бы сначала посмотрел на все строки.

In [1169]: a=np.array([[2,1,1,3],[3,3,2,1]])
In [1170]: a1=np.repeat(a,[2,1,3,4], axis=1)
In [1171]: a1
Out[1171]: 
array([[2, 2, 1, 1, 1, 1, 3, 3, 3, 3],
       [3, 3, 3, 2, 2, 2, 1, 1, 1, 1]])

Но cumsum для известного повтора решает это красиво:

In [1172]: ind=np.cumsum([2,1,3,4])-1
In [1173]: ind
Out[1173]: array([1, 2, 5, 9], dtype=int32)
In [1174]: np.take(a1,ind,axis=1)
Out[1174]: 
array([[2, 1, 1, 3],
       [3, 3, 2, 1]])
ответил hpaulj 2 PM00000070000001431 2016, 19:20:14
0
>>> import numpy as np
>>> x = np.repeat(np.array([[1,2],[3,4]]), 2, axis=1)
>>> y=[list(set(c)) for c in x] #This part remove duplicates for each array in tuple. So this will not work for x = np.repeat(np.array([[1,1],[3,3]]), 2, axis=1)=[[1,1,1,1],[3,3,3,3]. Result will be [[1],[3]]
>>> print y
[[1, 2], [3, 4]]

Вам не нужно знать ось и повторять сумму ...

ответил redratear 2 PM00000040000005431 2016, 16:55:54

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132