Какой самый эффективный способ написания [1: 20,25: 30] на python - PullRequest
0 голосов
/ 14 мая 2018

В matlab мы можем написать список от 1 до 30, исключая 21-24, используя [1:20,25:30]. Какой самый эффективный способ сделать это в Python?

Другой вопрос: существует ли эффективный способ удаления одного элемента в списке или столбца в ndarray в python? Это то же самое, что и в matlab , просто установив A[:,1]=[]?

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

В MATLAB / Octave

[1:20,25:30]

3 вещи происходят - 1:20, и 25:30 генерирует матрицы, и [ ] объединяет их в одну матрицу.

>> [1:20,25:30]
ans =
 Columns 1 through 16:
    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16
 Columns 17 through 26:
   17   18   19   20   25   26   27   28   29   30
>> A = 1:20;
>> B = 25:30;
>> [A, B]
ans =
 Columns 1 through 16:
    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16
 Columns 17 through 26:
   17   18   19   20   25   26   27   28   29   30

Эквивалент в numpy:

In [193]: A = np.arange(1,21);
In [194]: B = np.arange(25,31);
In [195]: np.concatenate((A,B))
Out[195]: 
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
       18, 19, 20, 25, 26, 27, 28, 29, 30])

Существуют и другие функции, которые делают то же самое, но все в конечном итоге используют concatenate, np.block, np.hstack, np.r_ и т. Д. concatenate - это основная numpy функция для объединения массивов по одному измерению или другой.


В Python вы можете удалять элементы из списка с похожим синтаксисом:

In [201]: alist = list(range(10))
In [202]: alist
Out[202]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [203]: alist[3:6] = []
In [204]: alist
Out[204]: [0, 1, 2, 6, 7, 8, 9]

Но это не работает с numpy массивами. Они имеют фиксированный размер. Лучшее, что вы можете сделать, это создать новый список без выбранных частей. Существует np.delete, который делает это за вас, но это скорее удобство, чем инструмент скорости.

In [205]: arr = np.arange(10)
In [207]: np.delete(arr, slice(3,6))
Out[207]: array([0, 1, 2, 6, 7, 8, 9])

delete делает разные вещи в зависимости от объекта удаления. Я думаю, что в этом случае он будет копировать фрагменты в новый массив

In [208]: res = np.zeros(10-3, arr.dtype)
In [209]: res[:3]=arr[:3]
In [210]: res[3:]=arr[6:]
In [211]: res
Out[211]: array([0, 1, 2, 6, 7, 8, 9])

или, может быть, просто:

In [212]: np.concatenate([arr[:3], arr[6:]])
Out[212]: array([0, 1, 2, 6, 7, 8, 9])

Особенно, если значения удаления представляют собой список, а не срез, delete использует mask:

In [213]: mask = np.ones(arr.shape, dtype=bool)
In [214]: mask[3:6]=0
In [215]: mask
Out[215]: 
array([ True,  True,  True, False, False, False,  True,  True,  True,
        True])
In [216]: arr[mask]
Out[216]: array([0, 1, 2, 6, 7, 8, 9])

MATLAB может делать некоторые из этих вещей быстрее, перенося большую часть действия в скомпилированный код. Но логика, я ожидаю, будет похожа.

0 голосов
/ 14 мая 2018

Самый эффективный способ в Python - это на один символ длиннее, если вы используете функцию с однобуквенным именем:

l(1,20,25,30)

Вам необходимо определить функцию l где-нибудь в вашей библиотеке служебных программ.:

def l(*args):
    pairs = args[:]
    res = []
    while len(pairs) > 1:
        res += range(pairs[0], pairs[1]+1)
        pairs = pairs[2:]
    assert len(pairs) == 0
    return res
  • Утверждение существует, чтобы убедиться, что вы ввели четное количество аргументов.
  • Копия args в pairs существует, чтобы вы не могли случайно изменить переменную, переданную в l, как в

    mypairs = [1,20,25,30]
    print(l(*mypairs))
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...