【问题标题】:Convert string of length n to a matrix of n x len(alphabet)将长度为 n 的字符串转换为 n x len(字母)的矩阵
【发布时间】:2019-12-28 05:18:36
【问题描述】:

假设我们从alphabet {'A', 'B', 'C', 'D', 'E', 'F'} 中得到一个长度为 n = 5 的 String "AABCD",维度为 len(alphabet) = 6。将这个字符串转换为 5 x 的 Pythonic 方法是什么? 6矩阵?

即。

#INPUT:
string = "AABCD"
alphabet = {'A', 'B', 'C', 'D', 'E', 'F'}
#OUTPUT
output = 
        A B C D E F
char 1[ 1 0 0 0 0 0 ]
char 2[ 1 0 0 0 0 0 ]
char 3[ 0 1 0 0 0 0 ]
char 4[ 0 0 1 0 0 0 ]
char 5[ 0 0 0 1 0 0 ]

我搜索了其他答案,但还没有找到类似的问题。非常感谢您的建议!

【问题讨论】:

  • 我在这个问题上问了一个类似的question。看看这是否有帮助。祝你好运!

标签: python numpy matrix


【解决方案1】:

一个简单的双循环就可以了

string = "AABCD"
alphabet = ['A', 'B', 'C', 'D', 'E', 'F']

matrix = [[0 for _ in range(len(alphabet))] for _ in range(len(string))]

for i, s in enumerate(string):
    for j, a in enumerate(alphabet):
        matrix[i][j] = 1 if s == a else 0

print(matrix)

输出将是

[
[1, 0, 0, 0, 0, 0], 
[1, 0, 0, 0, 0, 0], 
[0, 1, 0, 0, 0, 0], 
[0, 0, 1, 0, 0, 0], 
[0, 0, 0, 1, 0, 0]
]

也可以通过itertools.product 完成,但它看起来不像 for 循环那么干净。

import itertools

string = "AABCD"
alphabet = ['A', 'B', 'C', 'D', 'E', 'F']

string_iter = zip(list(range(len(string))), string)
alphabet_iter = zip(list(range(len(alphabet))), alphabet)

matrix = [[0 for _ in range(len(alphabet))] for _ in range(len(string))]

for (i, s), (j, a) in itertools.product(string_iter, alphabet_iter):
    matrix[i][j] = 1 if s == a else 0

print(matrix)

【讨论】:

    【解决方案2】:

    您可以使用此代码:

    string = "AABCD"
    #use array insted set type
    alphabet = ['A', 'B', 'C', 'D', 'E', 'F']
    #global matrix
    mat=[]
    #get length of string to create one-hot vector for evry  character
    l=len(alphabet)
    for i in string:
        indx=alphabet.index(i)
        sub=[0] * l
        sub[indx]=1
        mat.append(sub)
    

    输出:

    [[1, 0, 0, 0, 0, 0],
     [1, 0, 0, 0, 0, 0],
     [0, 1, 0, 0, 0, 0],
     [0, 0, 1, 0, 0, 0],
     [0, 0, 0, 1, 0, 0]]
    

    【讨论】:

    • 谢谢,这个答案在纯 Python 中是可以理解的。我意识到其他答案“更短”并坚持“Pythonic”的精神,但它们依赖于其他软件包。这个答案还具有更快的运行时间(与嵌套的 for 循环相比)
    • 这个答案与 for 循环答案具有相同的时间复杂度 O(len(string)*len(alphabet)),这对于说 string = "AABCX" 不起作用,因为 alphabet.index(i) 会抛出异常
    • 对不起@DeveshKumarSingh 我的错误!你是对的。
    【解决方案3】:

    另一个更简洁、可能更通用的解决方案:

    import numpy as np
    alphabet =["A","B","C","D","E","F"]
    
    
    alphabet_dict = {}
    for i,x in enumerate(alphabet):
       alphabet_dict[x] = i
    
    
    string = ["A", "A", "B", "C", "D"]
    
    output = np.zeros((len(alphabet), len(string)))
    
    for i,x in enumerate(string):
        output[i][alphabet_dict[x]] = 1
    

    希望这会有所帮助。

    【讨论】:

    • 如果其他人正在查看此答案:应切换最后一行的索引output[alphabet_dict[x]][i]
    【解决方案4】:

    对于您的确切输出:

    string = "AABCD"
    alphabet = ['A', 'B', 'C', 'D', 'E', 'F']
    
    print(f'output = \n\t{" ".join(alphabet)}')
    for ix,char in enumerate(string, start=1):
        x = [0]*len(alphabet)
        x[alphabet.index(char)] = 1
        print(f'char {ix} {x}'.replace(',',''))
    

    输出:

    output = 
            A B C D E F
    char 1 [1 0 0 0 0 0]
    char 2 [1 0 0 0 0 0]
    char 3 [0 1 0 0 0 0]
    char 4 [0 0 1 0 0 0]
    char 5 [0 0 0 1 0 0]
    

    【讨论】:

      【解决方案5】:

      你可以使用 pandas 来做这几行:

      import pandas as pd
      string1 = "AABCD"
      df = pd.Series([*string1]).str.get_dummies()
      df = df.rename(index=lambda x: f'Char {x+1}')
      print(df)
      

      输出为 pandas 数据框:

              A  B  C  D
      Char 1  1  0  0  0
      Char 2  1  0  0  0
      Char 3  0  1  0  0
      Char 4  0  0  1  0
      Char 5  0  0  0  1
      

      请注意,语法糖是使用[*'string'] 将字符串解包为字符列表,结果为['s','t','r','i','n','g']

      【讨论】:

        【解决方案6】:

        这是我的,它也适用于不同的尺寸值,如图所示:

        df = pd.DataFrame(((pd.Series([*string])*len(alphabet)).str.split("", n=-1, expand=True).drop(columns=[0, len(alphabet)+1]).eq(list(sorted(alphabet)))*1)).rename(index=lambda x: f'Char {x+1}', columns=lambda x: f'{chr(x+64)}')                                                                                                                                                                             
        
        In [1661]: df                                                                                                                                                                                  
        Out[1661]: 
                A  B  C  D  E  F
        Char 1  1  0  0  0  0  0
        Char 2  1  0  0  0  0  0
        Char 3  0  1  0  0  0  0
        Char 4  0  0  1  0  0  0
        Char 5  0  0  0  1  0  0
        

        string = 'AABCDEEF'
        alphabet = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'}
        
        df = pd.DataFrame(((pd.Series([*string])*len(alphabet)).str.split("", n=-1, expand=True).drop(columns=[0, len(alphabet)+1]).eq(list(sorted(alphabet)))*1)).rename(index=lambda x: f'Char {x+1}', columns=lambda x: f'{chr(x+64)}')
        
                A  B  C  D  E  F  G  H
        Char 1  1  0  0  0  0  0  0  0
        Char 2  1  0  0  0  0  0  0  0
        Char 3  0  1  0  0  0  0  0  0
        Char 4  0  0  1  0  0  0  0  0
        Char 5  0  0  0  1  0  0  0  0
        Char 6  0  0  0  0  1  0  0  0
        Char 7  0  0  0  0  1  0  0  0
        Char 8  0  0  0  0  0  1  0  0
        
        

        【讨论】:

        • 哈哈好“单线”
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多