【问题标题】:Mapping alphabets to its numeric equivalent?将字母映射到其等效数字?
【发布时间】:2022-01-21 16:23:02
【问题描述】:

请在下面查看我的代码。我正在遍历“1A”、“4D”等字符串,我希望输出改为 1.1、4.4 等......见下文。

我想要 1.1、1B= 1.2、4A = 4.1、5D = 5.4 等等,而不是 1A...

Convert alphabet letters to number in Python

data = ['1A','1B','4A', '5D','']
df = pd.DataFrame(data, columns = ['Score'])

newcol = []

for col, row in df['Score'].iteritems()
    if pd.isnull(row):
        newcol.append(row)       
    elif pd.notnull(row): 
        newcol.append(#FIRST ELEMENT OF ROW, 1-5,'.', 
                      #NUMERIC EQUIVALENT OF ALPHA, IE, A=1, B=2, C=3, D=4, etc)

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    你可以使用str.replace:

    df['Score'] = df['Score'].str.replace('\D',
                  lambda x: f'.{ord(x.group(0).upper())-64}', regex=True)
    

    输出:

      Score
    0   1.1
    1   1.2
    2   4.1
    3   5.4
    4      
    

    【讨论】:

      【解决方案2】:

      使用(带有@Ch3steR 的评论)-

      from string import ascii_uppercase
      dic = {j:str(i) for i,j in enumerate(ascii_uppercase, 1)}
      df['Score'].str[:-1] + '.' + df['Score'].str[-1].map(dic)
      

      输出

      0    1.1
      1    1.2
      2    4.1
      3    5.4
      4    NaN
      Name: Score, dtype: object
      

      【讨论】:

      • 您可以使用enumerate(iterable, 1) 代替在每次迭代中执行加法。
      • 当字符串为“11B”时,此解决方案不起作用。
      • @Ch3steR 是的,必须修改为 [:-1] 和 [-1] 索引器..完成
      • 用你的回答更新了我的回答。查看更新的时间安排和基准测试统计数据。
      【解决方案3】:

      您可以使用 str.maketransstr.translate 构建映射,这是将每个字符映射到其输出的常用方法。

      • str.maketrans

        此静态方法返回可用于 str.translate() 的转换表。

      • str.translate

        返回 s 的副本,其中所有字符都已通过映射映射,映射必须是 Unicode 序数(整数)到 Unicode 序数、字符串或无的字典。未映射的字符保持不变。

      使用pd.Series.apply 并将str.translate 传递给它。

      from string import ascii_uppercase
      
      table = str.maketrans({c: f'.{i}' for i, c in enumerate(ascii_uppercase, 1)})
      df['Score'].apply(str.translate, args=(table, ))
      
      # 0    1.1
      # 1    1.2
      # 2    4.1
      # 3    5.4
      # 4       
      # Name: Score, dtype: object
      

      Timeit 结果:

      基准设置

      def ch3ster(df):
          table = str.maketrans(
              {c: f".{i}" for i, c in enumerate(ascii_uppercase, 1)}
          )
          return df["Score"].apply(str.translate, args=(table,))
      
      
      def Vivek(df):
          dic = {j: str(i) for i, j in enumerate(ascii_uppercase, 1)}
          return df["Score"].str[:-1] + "." + df["Score"].str[-1].map(dic)
      
      
      def mozway(df):
          return df["Score"].str.replace(
              "\D", lambda x: f".{ord(x.group(0).upper())-64}", regex=True
          )
      
      
      def check(a, b):
          return (a == b).all()
      
      
      bench = perfplot.bench(
          setup=lambda n: pd.DataFrame(
              {
                  "Score": np.arange(n).astype(str)
                  + pd.Series([random.choice(ascii_uppercase) for _ in range(n)])
              }
          ),
          kernels=[ch3ster, Vivek, mozway],
          n_range=[10 ** i for i in range(1, 8)],
          xlabel="size of df",
          equality_check=check,
      )
      

      结果

      n ch3ster Vivek mozway
      10 0.000138986 0.000730289 0.000135238
      100 0.00018052 0.000789941 0.00021811
      1000 0.000569407 0.00126675 0.000882363
      10000 0.00471242 0.00610832 0.00777755
      100000 0.0578925 0.076809 0.0871657
      1000000 0.604576 0.738928 0.867847
      10000000 6.21429 7.11069 8.69433

      当 df 很大时:

      • 如果执行时间很重要,您可以使用maketrans + translate 解决方案。
      • 按执行时间排序(最短时间到最长时间)ch3ster

      df 较小时(小于 10K):

      • mozway 的解决方案和maketrans 几乎都需要相似的时间。 maketrans 稍微快一点。
      • 按执行时间排序(最短时间到最长时间)ch3ster

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-23
        • 1970-01-01
        相关资源
        最近更新 更多