I have a numpy array that looks something like this:
h = array([string1 1
string2 1
string3 1
string4 3
string5 4
string6 2
string7 2
string8 4
string9 3
string0 2 ])
In the second column, I would like to change all occurrences of 1 to 3, all occurrences of 3 to 2, all occurrences of 4 to 1
Obviously if I systematically try to do it in place I will get an error, because:
h[,:1 == 1] = 3
h[,:1 == 3] = 2
will change all the 1's into 2's
The matrix can be up to 50,000 elements long, and the values to change might vary
I was looking at a similar question here , but it was turning all digits to 0, and the answers were specific to that.
Is there a way to simultaneously change all these occurrences or am I going to have to find another way?
You can use a look up table and advanced indexing:
A = np.rec.fromarrays([np.array("The quick brown fox jumps over the lazy dog .".split()), np.array([1,1,1,3,4,2,2,4,3,2])])
A
# rec.array([('The', 1), ('quick', 1), ('brown', 1), ('fox', 3),
# ('jumps', 4), ('over', 2), ('the', 2), ('lazy', 4), ('dog', 3),
# ('.', 2)],
# dtype=[('f0', '<U5'), ('f1', '<i8')])
LU = np.arange(A['f1'].max()+1)
LU[[1,3,4]] = 3,2,1
A['f1'] = LU[A['f1']]
A
# rec.array([('The', 3), ('quick', 3), ('brown', 3), ('fox', 2),
# ('jumps', 1), ('over', 2), ('the', 2), ('lazy', 1), ('dog', 2),
# ('.', 2)],
# dtype=[('f0', '<U5'), ('f1', '<i8')])
The best way to do it is to use a dict to map a value. Doing so requires you to use a vectorized function:
import numpy as np
a = [[1,1],[1,2],[1,3]]
a = np.array([[1,1],[1,2],[1,3]])
>>> a
array([[1, 1],
[1, 2],
[1, 3]])
dic = {3:2,2:3}
vfunc = np.vectorize(lambda x:dic[x] if x in dic else x)
a[:,1] = vfunc(a[:,1])
>>> a
array([[1, 1],
[1, 3],
[1, 2]])
You can either use map
directly, or use the more efficient numpy.vectorize
to turn a mapping function into a function that can be applied to the array directly:
import numpy as np
mapping = {
1: 3,
3: 4,
4: 1
}
a = np.array([1, 2, 3, 4, 5, 1, 2, 3, 4, 5])
mapping_func = np.vectorize(lambda x: mapping[x] if x in mapping else x)
b = mapping_func(a)
print(a)
print(b)
Result:
[1 2 3 4 5 1 2 3 4 5]
[3 2 4 1 5 3 2 4 1 5]
Note that you don't have to use a dict
or a lambda
function. You function could be any normal function that takes the data type of your source array as an input ( int
in this case) and returns the data type of the target array.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.