#python #python-3.x #pandas #string #dictionary
Вопрос:
У меня есть df, содержащий строки с несколькими данными, которые я хочу проанализировать и сохранить в виде словаря. Я хотел бы сохранить PubMed Identifier
в качестве pmid
ключа и следующие цифры в качестве его значений, Embase
как euid
и следующие цифры, NCT
как trialid
и следующее число (без пробела), и игнорировать числа самостоятельно или игнорировать PubMed Identifier/Embase
без конечных/связанных цифр.
data = {"ORN": [1, 2, 3, 4],
"EN": ["PubMed Identifier 27955689", "PubMed Identifier 8010359Embase 24208639", "PubMed Identifier 12237786Embase 35148801", "PubMed Identifier NCT02360007 12537613"]
}
df = pd.DataFrame(data=data)
ORN EN
0 1 PubMed Identifier 27955689
1 2 PubMed Identifier 8010359Embase 24208639
2 3 PubMed Identifier 12237786Embase 35148801
3 4 PubMed Identifier NCT02360007 12537613
desired_df
ORN EN
0 1 {"pmid": 27955689}
1 2 {"pmid": 8010359, "euid": 24208639}
2 3 {"pmid": 12237786, "euid": 35148801}
3 4 {"trialid": 02360007}
Я не могу понять, что мне следует делать с наилучшим подходом. Моя идея разделить строку по столбцам, .split(expand=True)
а затем изменить порядок столбцов, а затем объединить их обратно с помощью a to_dict()
-лучшее, что я могу придумать, но любые лучшие предложения были бы замечательными. Манипуляции со строками-это то, в чем мне нужно совершенствоваться.
Комментарии:
1. извините — мне трудно следить за тем, что вы пытаетесь сделать. Вы пытаетесь построить несколько кадров данных, разделяя их по строкам в зависимости от того, находятся ли «Embase» или » NCT » во втором столбце? или вы пытаетесь проанализировать значения во втором столбце, разделив числа «Embase» и/или «NCT» на новые столбцы? Если бы вы могли показать нам, что вы хотите, чтобы произошло с вашим примером, это было бы действительно полезно. Имейте в виду, что мы не знаем этого набора данных/поля, поэтому единственное, в чем мы можем помочь, — это то, что вы нам расскажете 🙂
2. @MichaelDelgado Последний, хочу проанализировать значения во втором столбце
EN
и вернуть результаты , показанные сейчасdesired_df
, спасибо.3. Почему у ORN 4 нет pmid?
4. @MichaelDelgado, к сожалению, это происходит, без объяснения причин. Это то, что я получаю из своих поисковых запросов по этим библиографическим базам данных.
Ответ №1:
Извлеките данные с помощью .str.extract()
Создайте диктант с .apply()
помощью dropna()
to_dict()
:
- Извлеките данные с помощью
.str.extract()
df_extract = df['EN'].str.extract(r'PubMed Identifiers*(?:(?P<pmid>d )(?:Embases*(?P<euid>d ))?)|NCT(?P<trialid>d )')
или используйте:
df_extract = df['EN'].str.extract(r'PubMed Identifiers*(?P<pmid>d )?s*(?:Embases*(?P<euid>d ))?(?:NCTs*(?P<trialid>d ))?')
Результат:
print(df_extract)
pmid euid trialid
0 27955689 NaN NaN
1 8010359 24208639 NaN
2 12237786 35148801 NaN
3 NaN NaN 02360007
df_extract.apply(lambda x: x.dropna().to_dict(), axis=1)
Результат:
0 {'pmid': '27955689'}
1 {'pmid': '8010359', 'euid': '24208639'}
2 {'pmid': '12237786', 'euid': '35148801'}
3 {'trialid': '02360007'}
dtype: object
Ответ №2:
Создайте словарь сопоставлений, затем создайте шаблон регулярного выражения, чтобы найти все пары значений ключей из каждой строки, а затем переназначите пары ключ-значение в дикт
d = {'PubMed Identifier': 'pmid',
'Embase': 'emid', 'NCT': 'trialid'}
pat = fr'({"|".join(d)})s*(d )'
df['EN'].str.findall(pat).map(lambda l: {d[k]: v for k, v in l})
0 {'pmid': '27955689'}
1 {'pmid': '8010359', 'emid': '24208639'}
2 {'pmid': '12237786', 'emid': '35148801'}
3 {'trialid': '02360007'}
Name: EN, dtype: object
Ответ №3:
Вы можете использовать str.extract
:
df['EN'].str.extract('PubMed Identifier (?P<pmid>d )|NCT(?P<trialid>d )|Embase (?P<euid>[^ ] )')
выход:
pmid trialid euid
0 27955689 NaN NaN
1 8010359 NaN NaN
2 12237786 NaN NaN
3 NaN 02360007 NaN
Чтобы иметь как дикт, добавьте .T.to_dict()
:
df['EN'].str.extract('(?=PubMed Identifiers (?P<pmid>[^ ] d ))?|(?=Embases (?P<euid>d ))?').T.to_dict()
выход:
{0: {'pmid': '27955689', 'euid': nan},
1: {'pmid': '8010359', 'euid': nan},
2: {'pmid': '12237786', 'euid': nan},
3: {'pmid': 'NCT02360007', 'euid': nan}}
Комментарии:
1. Это близко, но не совсем там wrt для вывода, я должен перейти к просмотру выражений reg и использовать
.extract()
метод. Это выглядит очень полезным, спасибо.