numpy 如何将浮点矩阵转换为整数矩阵?

wvt8vs2t  于 2022-12-13  发布在  其他
关注(0)|答案(4)|浏览(229)

我有一个25乘25的矩阵

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

我想把所有的元素转换成字符串字母。
我已经尝试了以下代码,但没有工作。

for i in rows:
        for j in cols:
            for k in vals:
                solution[i][j] = chr(k + 64)

还有其他功能吗?谢谢!

tp5buhyn

tp5buhyn1#

怎么样:

out = (x + 64).astype(np.uint32).view('U1')

示例:

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')

您也可以改为从每一列产生单一连续字串:

>>> (x + 64).astype(np.uint32).view(f'U{x.shape[1]}')
array([['CNLFYSGURPEXIJAMWDTHVKQOB'],
       ['BISHMLTCJKQGWONVYREPDUFXA'],
       ['UROGEDFVQAMTCKBXJNLIPHYSW'],
       ['NMUACQELPOFSVDWJHXYBITRGK']], dtype='<U25')

或者,如注解中所示,由于数组表示一个25x25 Sudoku,您可以显示子块(大小为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')
计时

这个方法特别有效,因为它是矢量化的,而且view()本身不进行复制。

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)
0dxa2lsx

0dxa2lsx2#

list(map((lambda sol: [chr(k + 64) for k in sol]), solution))

zpf6vheq

zpf6vheq3#

请尝试以下操作:

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')

这是一个快速优雅的解决方案,做正是你需要的。
进一步说明:np.矢量化(函数,对象):它对 object 中的每个元素应用 function。在本例中,它应用我们的lambda x:chr(64+x)函数。这相当于写入:

def f(x):
    return char(64+x)

x.astype(int)简单地将x的所有元素转换为所需的相同类型int。
希望这有助于和快乐的编码!

hs1ihplo

hs1ihplo4#

有一种方法可以避免迭代,只使用numpy方法。

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

相关问题