使用python中的预定义值替换数组中的数字时出错

时间:2018-12-04 17:52:14

标签: python numpy

我正在尝试使用基于n值的新集合替换数组(重复0-99)中的值。例如。如果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 :(得分:2)

您可以使用np.putmask(请参见此处)将特定值替换为基于这些值的公式(请参见here)。

对于您的情况,您可以modulus:它比使用字典更容易,更快。这代表您想要的输入/输出吗?

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 7 10 10 10 10 10 10 10 10]

如果要使用字典,请在.get方法中设置默认值

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

答案 1 :(得分:1)

更正:

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=8d{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=8get(19)返回None,因此return dtype设置为object

对于n=9get(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

当您询问错误时,应该包括完整追溯,或者至少包含足够的内容,以便我们确切知道错误发生的位置。在我运行测试用例之前,这对我来说并不明显。