Как перекодировать целые числа в другие значения в python?

Я был удивлен, что этот вопрос еще не был задан. Дан массив целых

x = np.random.randint(1,4,10)

> array([3, 2, 1, 2, 1, 1, 3, 3, 2, 1])

Как я могу (легко) изменить все значения согласно некоторому систематическому правилу, такому как

x[x==1] = 5
x[x==2] = 6
x[x==3] = 7

> array([6, 5, 6, 7, 5, 5, 6, 5, 7, 6])

Правило может быть более сложным, чем это, например, перекодировать 1=2 а также 2=1 так что порядок играет роль.

3 ответа

В то время как другие могут предложить просто использовать словарь, я бы предложил использовать что-то, что на самом деле сделано для этого конкретного типа поведения, а не вручную, используя словарь, Python map функция.

map берет функцию и применяет ее к каждому входу и возвращает результат в виде списка. Так что вы бы создали свой if x == y, return z как функция и применить map(yourfunction, yourlist) к этому.

Хорошая вещь о map в том, что вы можете использовать его на любой итерируемой, а не только на вашем списке

Обычная версия Python

def numberfunc(x):
    if x == 1:
       return 5

    elif x == 2:
       return 6

    elif x== 3:
       return 7

    else:
        return x

x = [random.randint(1,4) for _ in range(10)]
# array([3, 2, 1, 2, 1, 1, 3, 3, 2, 1])

x = map(numberfunc, x)
# array([6, 5, 6, 7, 5, 5, 6, 5, 7, 6])

Numpy версия (Numpy использует vectorize как его map)

x = np.random.randint(1,4,10)
# array([3, 2, 1, 2, 1, 1, 3, 3, 2, 1])

x = x.vectorize(numberfunc)
# array([6, 5, 6, 7, 5, 5, 6, 5, 7, 6])

Кроме того, если ваша функция отображения чисел имела большое количество сравнений (больше, чем 3, которые вы перечислите здесь), вы можете рассмотреть возможность использования python dict чтобы увеличить производительность при заданном времени доступа O(1) бронированного элемента, например:

num_dict {1:5, 2:6, 3:7, ...}
def numberfunc(x):
        if x in num_dict:
            return num_dict[x]
        return x

Вы, вероятно, не захотите делать это в простом случае из-за брони, связанной с производительностью словаря во время выполнения и постоянными издержками. Амортизация в основном означает, что, принимая во внимание все операции, которые вы выполняете, которые бронируются, стоимость самых дорогих операций будет компенсирована дешевизной менее дорогих. Иногда словарная мутация может быть дорогой; В целом, многие словарные мутации не будут дорогими по сравнению с другими структурами данных. Словари также имеют большие издержки индексации по сравнению с такими вещами, как массивы. В наивной реализации вам, как правило, приходится перебирать списки по вашему ключу, чтобы найти свое значение, и в более сложных сценариях часто требуются более гарантированные накладные расходы.

Самый простой способ - просто перебирать массивы, заменяя значения.

rule = {1: 5, 2: 6, 3: 7}
x = x.vectorize(lambda x: rule[x] if x in rule else x)

Использование map сделать преобразование. map принимает функцию преобразования и список входных данных и выводит результат применения этой функции ко всем входным данным на систематической основе.

Например:

def mapping(i):
    if i == 1:
        return 5
    elif i == 2:
        return 6
    elif i == 3:
        return 7
    return i

print array(map(mapping, [3, 2, 1, 2, 1, 1, 3, 3, 2, 1]))
Другие вопросы по тегам