Ошибка замены чисел в массиве предопределенными значениями в Python - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь заменить значения в массиве (повторяющиеся 0-99) новым набором, основанным на значении n.Например,если n=0, значения 0,10,20..90 должны быть заменены на 0,1,2..9, а остальные должны быть 10. Следующий код работает нормально для всех значений n (0-8), кроме 9Для 9 это выдает сообщение long() argument must be a string or a number, not 'NoneType' Я много пытался отладить это, но не могу найти, в чем проблема.

import numpy as np
arr1=[[19][29][ 0][11][ 1][86][90][28][23][31][39][96][82][17][71][39][ 8][97]]
n = 9
d = {}
for i, j in zip(range(n, 100, 10), range(10)):
    d[i] = j
arr2 = np.vectorize(d.get)(arr1)
arr2[arr2 == None] = 10

arr1 - это исходный массив, а arr2это новый массив.

вывод должен быть

arr2=[[ 1] [ 2] [10] [10] [10] [10] [10] [10] [10] [10] [ 3] [10] [10] [10] [10] [ 3] [10] [10]]

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Исправление:

arr1=[[19],[29],[ 0],[11],[ 1],[86],[90],[28],[23],[31],[39],[96],[82],[17],[71],[39],[ 8],[97]]

d:

{9: 0, 19: 1, 29: 2, 39: 3, 49: 4, 59: 5, 69: 6, 79: 7, 89: 8, 99: 9}

Ошибка, при полная обратная связь , составляет:

Traceback (most recent call last):
  File "stack53618793.py", line 8, in <module>
    arr2 = np.vectorize(d.get)(arr1)
  File "/usr/local/lib/python3.6/dist-packages/numpy/lib/function_base.py", line 1972, in __call__
    return self._vectorize_call(func=func, args=vargs)
  File "/usr/local/lib/python3.6/dist-packages/numpy/lib/function_base.py", line 2051, in _vectorize_call
    res = array(outputs, copy=False, subok=True, dtype=otypes[0])
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

С n=8 d равно {8: 0, 18: 1, 28: 2, 38: 3, 48: 4, 58: 5, 68: 6, 78: 7, 88: 8, 98: 9}.arr2 имеет много None, потому что это значение по умолчанию для get.

vectorize выполняет тестовый расчет с первым элементом arr1 и использует результат для установки возврата dtype.

С n=8, get(19) возвращает None, поэтому dtype возврата имеет значение object.

С n=9, get(19) возвращает целое число 1 (он находится в d), поэтому возвращаемый тип dtype - int.Это приводит к ошибке, когда другой get возвращает None.

Одним из исправлений является установка otypes.

arr2 = np.vectorize(d.get, otypes=[object])(arr1)

Другой возможностью является замена get на `get (

arr2 = np.vectorize(lambda x: d.get(x,10))(arr1)

Тогда вам не нужен шаг None замены.

Этот векторизация get, вероятно, не самый быстрый способ сделать эту замену. Но если вы делаетеиспользуйте vectorize, вам нужно следить за такими ловушками, как это автоматическое otypes.

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

0 голосов
/ 04 декабря 2018

Вы можете использовать np.putmask (см. Здесь), чтобы заменить конкретные значения формулой, основанной на этих значениях (см. здесь ).

Что касается вашего случая, вы можете модуль : это проще и быстрее, чем использовать словарь.Представляет ли это ваш желаемый вход / выход?

import numpy as np
n = 9

arr1=np.random.randint(0, 100, size=20)
arr2 = arr1.copy()
np.putmask(arr2, (arr1-n)%10 == 0, arr1 % 10)

print(arr1)
print(arr2)

[69 70 63 52 27 96 0 40 2 90 36 24 17 90 67 58 74 50 11 58]

[9 70 63 52 27 96 0 40 2 90 36 24 17 90 67 58 74 50 11 58]

Отредактировано для желаемого результата:

n = 9 
arr1=np.random.randint(0, 100, size=20)
arr2 = arr1.copy()
mask = (arr1-n)%10 == 0
np.putmask(arr2, mask , arr1 // 10)
np.putmask(arr2, ~mask , 10)
print(arr1)
print(arr2)

[28 72 87 31 87 3 34 96 61 14 25 79 74 25 38 87 38 8 6 8] [10 10 10 10 10 10 10 10 10 10 10 7 10 10 10 10 10 10 10 10]

Если вы хотите использовать словарь, установите значение по умолчанию в методе .get

arr2 = np.vectorize(lambda x: d.get(x,10))(arr1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...