Получить оба числа в скобках строки Regex Python

У меня есть такая колонка 'cost_money',

0    According to different hospitals, the charging...
1    According to different hospitals, the charging...
2    According to different conditions, different h...
3    According to different hospitals, the charging...
Name: cost_money, dtype: object

Из которых в каждой строке есть важные данные в скобках, которые мне нужно извлечь.

"According to different hospitals, the charging standard is inconsistent, the city's three hospitals is about (1000-4000 yuan)"

Моя попытка для этого,

import regex as re

full_df['cost_money'] = full_df.cost_money.str.extract('\((.*?)\')
full_df

Но это дает ошибку между преобразованием строки и int, я думаю. Это целая строка, и если я напечатаю любой символ, он будет типа char. Кроме этого, мне не нужно слово «юань» из скобок, поэтому мой метод прямого извлечения чисел был

import regex as re
df['cost_money'].apply(lambda x: re.findall(r"[-+]?\d*\.\d+|\d+", x)).tolist()
full_df['cost_money']

Ошибка:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
c:\Users\Siddhi\HealthcareChatbot\eda.ipynb Cell 11' in <module>
      1 import regex as re
----> 2 df['cost_money'].apply(lambda x: re.findall(r"[-+]?\d*\.\d+|\d+", x)).tolist()
      3 full_df['cost_money']

File c:\Users\Siddhi\HealthcareChatbot\venv\lib\site-packages\pandas\core\series.py:4433, in Series.apply(self, func, convert_dtype, args, **kwargs)
   4323 def apply(
   4324     self,
   4325     func: AggFuncType,
   (...)
   4328     **kwargs,
   4329 ) -> DataFrame | Series:
   4330     """
   4331     Invoke function on values of Series.
   4332 
   (...)
   4431     dtype: float64
   4432     """
-> 4433     return SeriesApply(self, func, convert_dtype, args, kwargs).apply()

File c:\Users\Siddhi\HealthcareChatbot\venv\lib\site-packages\pandas\core\apply.py:1082, in SeriesApply.apply(self)
   1078 if isinstance(self.f, str):
   1079     # if we are a string, try to dispatch
   1080     return self.apply_str()
-> 1082 return self.apply_standard()

File c:\Users\Siddhi\HealthcareChatbot\venv\lib\site-packages\pandas\core\apply.py:1137, in SeriesApply.apply_standard(self)
   1131         values = obj.astype(object)._values
   1132         # error: Argument 2 to "map_infer" has incompatible type
   1133         # "Union[Callable[..., Any], str, List[Union[Callable[..., Any], str]],
   1134         # Dict[Hashable, Union[Union[Callable[..., Any], str],
   1135         # List[Union[Callable[..., Any], str]]]]]"; expected
   1136         # "Callable[[Any], Any]"
-> 1137         mapped = lib.map_infer(
   1138             values,
   1139             f,  # type: ignore[arg-type]
   1140             convert=self.convert_dtype,
   1141         )
   1143 if len(mapped) and isinstance(mapped[0], ABCSeries):
   1144     # GH#43986 Need to do list(mapped) in order to get treated as nested
   1145     #  See also GH#25959 regarding EA support
   1146     return obj._constructor_expanddim(list(mapped), index=obj.index)

File c:\Users\Siddhi\HealthcareChatbot\venv\lib\site-packages\pandas\_libs\lib.pyx:2870, in pandas._libs.lib.map_infer()

c:\Users\Siddhi\HealthcareChatbot\eda.ipynb Cell 11' in <lambda>(x)
      1 import regex as re
----> 2 df['cost_money'].apply(lambda x: re.findall(r"[-+]?\d*\.\d+|\d+", x)).tolist()
      3 full_df['cost_money']

File c:\Users\Siddhi\HealthcareChatbot\venv\lib\site-packages\regex\regex.py:338, in findall(pattern, string, flags, pos, endpos, overlapped, concurrent, timeout, ignore_unused, **kwargs)
    333 """Return a list of all matches in the string. The matches may be overlapped
    334 if overlapped is True. If one or more groups are present in the pattern,
    335 return a list of groups; this will be a list of tuples if the pattern has
    336 more than one group. Empty matches are included in the result."""
    337 pat = _compile(pattern, flags, ignore_unused, kwargs, True)
--> 338 return pat.findall(string, pos, endpos, overlapped, concurrent, timeout)

TypeError: expected string or buffer

Я пробовал то же самое, используя findall, но в большинстве сообщений упоминалось использование экстракта, поэтому я придерживался этого.

МОЙ ЗАПРОШЕННЫЙ ВЫВОД:

[5000, 8000]
[6000, 7990]
..SO ON

Может кто-нибудь, пожалуйста, помогите мне? Спасибо

Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
2
0
32
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать (\d*-\d*), чтобы сопоставить часть числа, а затем разделить на -.

df['money'] = df['cost_money'].str.extract('\((\d*-\d*).*\)')
df['money'] = df['money'].str.split('-')

Или используйте (\d*)[^\d]*(\d*), чтобы сопоставить две части числа по отдельности.

df['money'] = df['cost_money'].str.extract('\((\d*)[^\d]*(\d*).*\)').values.tolist()
Ответ принят как подходящий

Я считаю, что ваше регулярное выражение было неверным. Вот альтернативы.

Пример ввода:

df = pd.DataFrame({'cost_money': ['random text (123-456 yuans)',
                                  'other example (789 yuans)']})

Вариант А:

df['cost_money'].str.extract('\((\d+-\d+)', expand=False)

Вариант B (разрешить единую стоимость):

df['cost_money'].str.extract('\((\d+(?:-\d+)?)', expand=False)

Вариант C (все числа съедают первый '(' в виде списка:

df['cost_money'].str.split('[()]').str[1].str.findall('(\d+)')

Вывод (назначается как новые столбцы):

                    cost_money        A        B           C
0  random text (123-456 yuans)  123-456  123-456  [123, 456]
1    other example (789 yuans)      NaN      789       [789]

Другие вопросы по теме