Как заменить определенное слово в кадре данных, только если ему предшествует число? - PullRequest
2 голосов
/ 12 мая 2019

Я пытаюсь найти в кадре данных определенные слова, перечисленные в значениях словаря, если они существуют, они будут заменены ключом значений.

units_dic= {'grams':['g','Grams'],
                'kg'   :['kilogram','kilograms']}

проблема в том, что в некоторых единицах измерения сокращения являются буквами, поэтому они также заменят все буквы. Я хочу выполнить замену, только если ей предшествует число, чтобы убедиться, что это единица измерения.

Dataframe

    Id | test 
    ---------
    1  |'A small paperclip has a mass of about 111 g'
    2  |'1 kilogram =1000 g'
    3  |'g is the 7th letter in the ISO basic Latin alphabet'

Запасной контур

  x = df.copy()
  for k in units_dic:
      for i in range(len(x['test'])):
          for w in units_dic[k]:
              x['test'][i] = str(x['test'][i]).replace(str(w), str(k))

Выход

    Id | test 
    ---------
    1  |'A small paperclip has a mass of about 111 grams'
    2  |'1 kg =1000 grams'
    3  |'grams is the 7th letter in the ISO basic Latin alphabet'

Ответы [ 3 ]

1 голос
/ 12 мая 2019

Регулярные выражения для спасения вместе с листанием словаря.

import re

d = {i: k for k, v in units_dic.items() for i in v}
u = r'|'.join(d)
v = fr'(\d+\s?)\b({u})\b'

df.assign(test=[re.sub(v, lambda x: x.group(1) + d[x.group(2)], el) for el in df.test])

   Id                                               test
0   1    A small paperclip has a mass of about 111 grams
1   2                                   1 kg =1000 grams
2   3  g is the 7th letter in the ISO basic Latin alp...
1 голос
/ 12 мая 2019

Попробуйте:

for key, val in units_dic.items(): 
    df['test'] = df['test'].replace("\d+[ ]*" + "|".join(val) , key , regex=True)
0 голосов
/ 12 мая 2019

Здесь мы можем использовать lookbehind функцию regex, что позволяет указать, что ей должен предшествовать номер, а необязательно пробел:

for k, v in units_dic.items():
    df['test'] = df['test'].str.replace(f"(?<=[0-9])\s*({'|'.join(v)})\b", f' {k}')

print(df)
   Id                                               test
0   1  'A small paperclip has a mass of about 111 grams'
1   2                                 '1 kg =1000 grams'
2   3  'g is the 7th letter in the ISO basic Latin al...

Пояснение
Сначала мы используем raw + fstring: fr'sometext'

Регулярное выражение:

  • ?<=[0-9] =перед номером
  • \s* стоит пробел
  • "|".join(v) возвращает нам значения в вашем словаре, разделенные |, который является оператором or в регулярном выражении
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...