用字母替换数组中的数字

时间:2019-07-16 13:44:12

标签: python arrays numpy

我正在尝试将数组中的数字转换为字母。因此,'001'将更改为'A''002'将更改为'B',一直到'025'更改为'Y'

到目前为止,我已经尝试使用字典来替换值,但这似乎不起作用,使用np.place不起作用,因为这是一个if / else条件,并且我拥有更多的变量。

Polymer_data = Polymer_data.sort_values(['ID'])
for i in Polymer_data.ID:
    first_arr = np.array(i.split('-'))
    print(first_arr)

数组中数据的一小部分

['001' '001' '001' '021']
['001' '001' '001' '022']
['006' '009' '019' '016']
['006' '009' '019' '017']
['019' '025' '001' '025']
['019' '025' '002' '022']
['025' '013' '025' '025']
['025' '014' '017' '025']
['025' '014' '020' '025']
['025' '015' '022' '025']
['025' '015' '025' '025']
['025' '017' '017' '025']
['025' '017' '017' '025']

因此,以上数据应转换为

['A' 'A' 'A' 'U']
['A' 'A' 'A' 'V']
['F' 'I' 'S' 'P']
['F' 'I' 'S' 'Q']
['S' 'Y' 'A' 'Y']
['S' 'Y' 'B' 'V']
['Y' 'M' 'Y' 'Y']
['Y' 'N' 'Q' 'Y']
['Y' 'N' 'T' 'Y']
['Y' 'O' 'V' 'Y']
['Y' 'O' 'Y' 'Y']
['Y' 'Q' 'Q' 'Y']
['Y' 'Q' 'Q' 'Y']

编辑:对代码进行格式化

就数组结构“ 001”至“ 025”而言,它也按四个顺序排列,重复该过程直到考虑到所有排列为止,因此数组的完整列表超过180000行。

5 个答案:

答案 0 :(得分:1)

我建议像这样使用“ chr()”:

def numToChar(num):
    asciiInt = int(num) + 64
    character = str(chr(asciiInt))
    return character

a = '002'    
print(numToChar(a)) # prints 'B'

编辑:

假设您的数据如下所示:

arr = ['001', '001', '001', '021', '001', '001', '001', '022', '006', '009', '019', '016', '006', '009', '019', '017', '019', '025', '001', '025', '019', '025', '002', '022', '025', '013', '025', '025', '025', '014', '017', '025']


def numToChar(num):
    asciiInt = int(num) + 64
    character = str(chr(asciiInt))
    return character


for i in range(len(arr)):
    arr[i] = numToChar(arr[i])


print(arr)
# Would print ['A', 'A', 'A', 'U', 'A', 'A', 'A', 'V', 'F', 'I', 'S', 'P', 'F', 'I', 'S', 'Q', 'S', 'Y', 'A','Y', 'S', 'Y', 'B', 'V', 'Y', 'M', 'Y', 'Y', 'Y', 'N', 'Q', 'Y']

答案 1 :(得分:1)

我这样做的方法是创建一个将整数映射为字母的字典,并使用np.vectorizedict.get将其映射到数组中的值:

from string import ascii_uppercase
d = dict(enumerate(ascii_uppercase))
# {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F'...
np.vectorize(d.get)(a.astype(int)-1)

array([['A', 'A', 'A', 'U'],
       ['A', 'A', 'A', 'V'],
       ['F', 'I', 'S', 'P'],
       ['F', 'I', 'S', 'Q'],
       ['S', 'Y', 'A', 'Y'],
       ['S', 'Y', 'B', 'V'],
       ['Y', 'M', 'Y', 'Y'],
       ['Y', 'N', 'Q', 'Y'],
       ['Y', 'N', 'T', 'Y'],
       ['Y', 'O', 'V', 'Y'],
       ['Y', 'O', 'Y', 'Y'],
       ['Y', 'Q', 'Q', 'Y'],
       ['Y', 'Q', 'Q', 'Y']], dtype='<U1')

答案 2 :(得分:1)

如果速度是一个问题,则可以在创建映射数组并将数组首先转换为实整数的情况下对该操作进行矢量化处理。

import string
map = np.array(list(string.ascii_uppercase))
data = data.astype(int)

map[data - 1]
# array([['A', 'A', 'A', 'U'],
#        ['A', 'A', 'A', 'V'],
#        ['F', 'I', 'S', 'P'],
#        ['F', 'I', 'S', 'Q'],
#        ['S', 'Y', 'A', 'Y'],
#        ['S', 'Y', 'B', 'V'],
#        ['Y', 'M', 'Y', 'Y'],
#        ['Y', 'N', 'Q', 'Y'],
#        ['Y', 'N', 'T', 'Y'],
#        ['Y', 'O', 'V', 'Y'],
#        ['Y', 'O', 'Y', 'Y'],
#        ['Y', 'Q', 'Q', 'Y'],
#        ['Y', 'Q', 'Q', 'Y']], dtype='<U1')

答案 3 :(得分:0)

您可以使用string模块在​​整数和ascii字符之间创建映射:

import string

alphabet = string.ascii_uppercase

numbers = ["001", "0022", "003", "005"]
letters = [alphabet[int(number)-1] for number in numbers]
print(letters)

返回

['A', 'V', 'C', 'E']

答案 4 :(得分:0)

我们可以转换为int/uint dtype,向其添加64使其转换为与这些数字等效的ascii,然后简单地将其视为字符串格式。视图部分实际上在运行时是免费的,因此应该非常有效-

# a is input array
def convert_to_char_typeconv(a):
    return (a.astype(np.uint32)+64).view('U1')

另一种方法是查看uint8/uint4个dtype值,将每个三元组转换为一个数字,然后以字符串格式查看。同样,ascii等效的想法将进入该方法。因此,实现将是-

def convert_to_char_view_sumr(a):    
    b = (a.view('u4')-48).reshape(-1,3)[:,1:]
    return (b[:,0]*10+b[:,1]+64).view('U1').reshape(len(a),-1)

样品运行-

# Input array of dtype <U3
In [419]: a
Out[419]: 
array([['001', '001', '001', '021'],
       ['001', '017', '001', '022']], dtype='<U3')

In [420]: convert_to_char_typeconv(a)
Out[420]: 
array([['A', 'A', 'A', 'U'],
       ['A', 'Q', 'A', 'V']], dtype='<U1')

In [421]: convert_to_char_view_sumr(a)
Out[421]: 
array([['A', 'A', 'A', 'U'],
       ['A', 'Q', 'A', 'V']], dtype='<U1')

基准化

其他发布的方法-

import string
from string import ascii_uppercase

# @neko's soln
def neko(numbers):
    alphabet = string.ascii_uppercase
    letters = [alphabet[int(number)-1] for number in numbers]
    return letters

# @yatu's soln
def yatu(a):
    d = dict(enumerate(ascii_uppercase))
    return np.vectorize(d.get)(a.astype(int)-1)

# @Nils Werner's soln
def nils(data):
    map = np.array(list(string.ascii_uppercase))
    data = data.astype(int)
    return map[data - 1]

180000行数据的计时-

要设置输入数据,我们使用具有两行的示例a,并在各行中重复90000x次,以模拟OP在180000行中的情况。

In [425]: a
Out[425]: 
array([['001', '001', '001', '021'],
       ['001', '017', '001', '022']], dtype='<U3')

In [426]: a = np.repeat(a,90000,axis=0)

In [427]: %timeit neko(a.ravel())
     ...: %timeit yatu(a)
     ...: %timeit nils(a)
254 ms ± 1.89 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
285 ms ± 1.71 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
206 ms ± 882 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [428]: %timeit convert_to_char_typeconv(a)
     ...: %timeit convert_to_char_view_sumr(a)
206 ms ± 1.61 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
2.83 ms ± 20.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)