I have a 25 by 25 matrix looks like
solution = array([[ 3, 14, 12, 6, 25, 19, 7, 21, 18, 16, 5, 24, 9, 10, 1, 13,
23, 4, 20, 8, 22, 11, 17, 15, 2],
[ 2, 9, 19, 8, 13, 12, 20, 3, 10, 11, 17, 7, 23, 15, 14, 22,
25, 18, 5, 16, 4, 21, 6, 24, 1],
[21, 18, 15, 7, 5, 4, 6, 22, 17, 1, 13, 20, 3, 11, 2, 24,
10, 14, 12, 9, 16, 8, 25, 19, 23],
...
...
[14, 13, 21, 1, 3, 17, 5, 12, 16, 15, 6, 19, 22, 4, 23, 10,
8, 24, 25, 2, 9, 20, 18, 7, 11]])
I want to convert all elements into string letters. For example, now solution[0][2]=12
, and in my new solution it should be solution_new[0][2]='L'.
I've tried the following code but didn't work.
for i in rows:
for j in cols:
for k in vals:
solution[i][j] = chr(k + 64)
Is there any other function? Thanks!
How about:
out = (x + 64).astype(np.uint32).view('U1')
Example:
x = np.array([
[3, 14, 12, 6, 25, 19, 7, 21, 18, 16, 5, 24,
9, 10, 1, 13, 23, 4, 20, 8, 22, 11, 17, 15, 2],
[ 2, 9, 19, 8, 13, 12, 20, 3, 10, 11, 17, 7, 23,
15, 14, 22, 25, 18, 5, 16, 4, 21, 6, 24, 1],
[21, 18, 15, 7, 5, 4, 6, 22, 17, 1, 13, 20,
3, 11, 2, 24, 10, 14, 12, 9, 16, 8, 25, 19, 23],
[14, 13, 21, 1, 3, 17, 5, 12, 16, 15, 6, 19, 22,
4, 23, 10, 8, 24, 25, 2, 9, 20, 18, 7, 11]
], dtype=float)
>>> x.dtype
dtype('float64')
>>> (x + 64).astype(np.uint32).view('U1')
array([['C', 'N', 'L', 'F', 'Y', 'S', 'G', 'U', 'R', 'P', 'E', 'X', 'I',
'J', 'A', 'M', 'W', 'D', 'T', 'H', 'V', 'K', 'Q', 'O', 'B'],
['B', 'I', 'S', 'H', 'M', 'L', 'T', 'C', 'J', 'K', 'Q', 'G', 'W',
'O', 'N', 'V', 'Y', 'R', 'E', 'P', 'D', 'U', 'F', 'X', 'A'],
['U', 'R', 'O', 'G', 'E', 'D', 'F', 'V', 'Q', 'A', 'M', 'T', 'C',
'K', 'B', 'X', 'J', 'N', 'L', 'I', 'P', 'H', 'Y', 'S', 'W'],
['N', 'M', 'U', 'A', 'C', 'Q', 'E', 'L', 'P', 'O', 'F', 'S', 'V',
'D', 'W', 'J', 'H', 'X', 'Y', 'B', 'I', 'T', 'R', 'G', 'K']],
dtype='<U1')
You can also make a single contiguous string from each row instead:
>>> (x + 64).astype(np.uint32).view(f'U{x.shape[1]}')
array([['CNLFYSGURPEXIJAMWDTHVKQOB'],
['BISHMLTCJKQGWONVYREPDUFXA'],
['UROGEDFVQAMTCKBXJNLIPHYSW'],
['NMUACQELPOFSVDWJHXYBITRGK']], dtype='<U25')
Or since, as indicated in comments, the array represents a 25x25 Sudoku, you could show the sub-blocks (size 5):
>>> (x + 64).astype(np.uint32).view(f'U5')
array([['CNLFY', 'SGURP', 'EXIJA', 'MWDTH', 'VKQOB'],
['BISHM', 'LTCJK', 'QGWON', 'VYREP', 'DUFXA'],
['UROGE', 'DFVQA', 'MTCKB', 'XJNLI', 'PHYSW'],
['NMUAC', 'QELPO', 'FSVDW', 'JHXYB', 'ITRGK']], dtype='<U5')
This method is particularly efficient, given that it is vectorized and view()
itself doesn't make a copy. Here on a 1-million element array:
n, m = 1000, 1000
x = np.random.randint(0, 26, size=(n, m))
%timeit %timeit (64 + x).astype(np.uint32).view('U1')
1.2 ms ± 3.45 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
# by contrast, my earlier solution
%timeit np.apply_along_axis(np.vectorize(chr), 1, 64 + x.astype(int))
177 ms ± 190 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# other solutions as of this writing
%timeit list(map((lambda sol: [chr(k + 64) for k in sol]), x))
233 ms ± 1.65 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit np.vectorize(lambda x: chr(64+x))(x.astype(int))
268 ms ± 280 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
list(map((lambda sol: [chr(k + 64) for k in sol]), solution))
Try the following:
import numpy as np
x = np.array([[1.,2.,3.],[4.,5.,6.]])
np.vectorize(lambda x: chr(64+x))(x.astype(int))
>>> array([['A', 'B', 'C'],
['D', 'E', 'F']], dtype='<U1')
Its a quick elegant solution that does exactly what you need.
Further Explanation: np.vectorize(function, object): It applies the function per element in object . In this case it applies our lambda x: chr(64+x) function to each element. This is the equivalent of writing:
def f(x):
return char(64+x)
for each element of the object. x.astype(int)
simply converts all elements of x to the same type int like you want.
Hope this helps and happy coding!
There is a way to avoid iterations and use numpy
methods only.
>>> solution = np.array([[3, 14, 12, 6, 25, 19, 7, 21, 18, 16, 5, 24, 9, 10, 1, 13, 23, 4, 20, 8, 22, 11, 17, 15, 2],
[2, 9, 19, 8, 13, 12, 20, 3, 10, 11, 17, 7, 23, 15, 14, 22, 25, 18, 5, 16, 4, 21, 6, 24, 1],
[21, 18, 15, 7, 5, 4, 6, 22, 17, 1, 13, 20, 3, 11, 2, 24, 10, 14, 12, 9, 16, 8, 25, 19, 23],
[14, 13, 21, 1, 3, 17, 5, 12, 16, 15, 6, 19, 22, 4, 23, 10, 8, 24, 25, 2, 9, 20, 18, 7, 11]])
def convert(solution):
seq = (solution+64).astype(np.uint8).tobytes() #~15% of time
out = np.frombuffer(seq, dtype='S1').astype('U').reshape(solution.shape) #~85% of time
return out
>>> convert(solution)
array([['C', 'N', 'L', 'F', 'Y', 'S', 'G', 'U', 'R', 'P', 'E', 'X', 'I',
'J', 'A', 'M', 'W', 'D', 'T', 'H', 'V', 'K', 'Q', 'O', 'B'],
['B', 'I', 'S', 'H', 'M', 'L', 'T', 'C', 'J', 'K', 'Q', 'G', 'W',
'O', 'N', 'V', 'Y', 'R', 'E', 'P', 'D', 'U', 'F', 'X', 'A'],
['U', 'R', 'O', 'G', 'E', 'D', 'F', 'V', 'Q', 'A', 'M', 'T', 'C',
'K', 'B', 'X', 'J', 'N', 'L', 'I', 'P', 'H', 'Y', 'S', 'W'],
['N', 'M', 'U', 'A', 'C', 'Q', 'E', 'L', 'P', 'O', 'F', 'S', 'V',
'D', 'W', 'J', 'H', 'X', 'Y', 'B', 'I', 'T', 'R', 'G', 'K']],
dtype='<U1')
>>> %timeit convert(solution)
11.9 µs ± 158 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each
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.