Пожалуйста, смотрите мой код ниже. Я перебираю такие строки, как «1A», «4D» и т. д., и хочу, чтобы на выходе вместо этого было 1,1, 4,4 и т. д. см. ниже.

Вместо 1А я хочу 1.1, 1В= 1.2, 4А = 4.1, 5D = 5.4 и т.д...

Преобразование букв алфавита в числа в 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)
2
SPena 19 Янв 2022 в 19:26

3 ответа

Вы можете использовать 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
mozway 19 Янв 2022 в 19:38
Сначала я думал, что regex будет медленным, но это быстрее, чем я ожидал. Я добавил результаты timeit в свой ответ. Хороший (уже проголосовал).
 – 
Ch3steR
19 Янв 2022 в 20:15

Используйте (с комментарием @Ch3steR) -

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

Вывод

0    1.1
1    1.2
2    4.1
3    5.4
4    NaN
Name: Score, dtype: object
2
Vivek Kalyanarangan 19 Янв 2022 в 19:55
1
Вместо этого вы можете использовать enumerate(iterable, 1) для выполнения сложения на каждой итерации.
 – 
Ch3steR
19 Янв 2022 в 19:53
Это решение не работает, когда строка, скажем, «11B».
 – 
Ch3steR
19 Янв 2022 в 20:16

Вы можете построить сопоставление, используя str.maketrans и str.translate , общий рецепт сопоставления каждого символа с его выводом.

  • str.maketrans

    Этот статический метод возвращает таблицу перевода, которую можно использовать для функции str.translate().

  • str.translate

    Возвратите копию s, где все символы были сопоставлены с помощью карты, которая должна быть словарем порядковых номеров Unicode (целых чисел) в порядковые номера Unicode, строки или None. Несопоставленные символы остаются нетронутыми.

Используйте 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 результаты:

  • настройка бенчмаркинга
    # млн строк  символы = np.arange(1_000_000).astype(str) + pd.Series([random.choice(ascii_uppercase) for _ in range(1_000_000)])  df = pd.DataFrame({"Оценка": символы})  
  • Результаты
    @Ch3ster  582 мс ± 4,42 мс на цикл (среднее значение ± стандартное отклонение для 7 запусков, по 1 циклу в каждом)   @Мозвэй  1,03 с ± 46,2 мс на цикл (среднее значение ± стандартное отклонение для 7 запусков, по 1 циклу в каждом)   @Вивек  Другой вывод (на момент написания опубликованного ответа                    работает только со строкой размера два)  

Когда df большой:

  • Если время выполнения имеет значение, вы можете использовать решение maketrans + translate.

Когда df маленький (размер менее 50 КБ):

  • И решение mozway, и maketrans занимают почти одинаковое время. maketrans немного быстрее.
1
Ch3steR 19 Янв 2022 в 20:14
1
Спасибо за сравнение ;)
 – 
mozway
19 Янв 2022 в 20:19