Эффективный способ найти строки в пандах со столбцами, удовлетворяющими определенным условиям - PullRequest
0 голосов
/ 09 сентября 2018

Меня интересует очень «пандоподобное» решение следующей проблемы. У меня есть простая реализация с циклической обработкой строк и проверкой условий в обоих столбцах. Я работаю над проблемой НЛП и мне нужно найти токены в предложениях. У меня есть два кадра данных, один с позициями токенов (лекарств) start_0 и end_0, а второй - с предложениями start_1 и end_1. Например:

Положение токенов:

 df_0 =

 start_0   end_0    token
0     20      27    aspirin
1     50      59    trazodone
2     81      88    placebo
3    121     127    haldol

Положение предложений:

 df_1=

    start_1 end_1
0         0    17
1        17    29
2        29    46
3        46    64
4        64    76
5        76    81
6        81    97
7        97   227

Мне нужно создать новый столбец в df_1 и поместить в соответствующую строку токен, а именно:

df_1 =

    start_1 end_1     token
0         0    17       NaN
1        17    29   aspirin
2        29    46       NaN
3        46    64 trazodone
4        64    76       NaN
5        76    81       NaN
6        81    97   placebo
7        97   227    haldol

Просто сопоставьте два фрейма данных, если позиция токена находится внутри предложения. Должно быть простое решение с функциональностью Pandas, а не циклическое прохождение строк и проверка обеих границ.

Ответы [ 2 ]

0 голосов
/ 09 сентября 2018

Вы можете попробовать использовать цикл for для достижения этой цели.Я не мог придумать его векторизованную версию.

import pandas as pd

df_0 = pd.DataFrame([[20, 27, "aspirin"], [50, 59, "trazodone"], [81, 88, "placebo"], [121, 127, "haldol"]], columns=["start_0", "end_0", "token"])
df_1 = pd.DataFrame([[0, 17], [17, 29], [29, 46], [46, 64], [64, 76], [76, 81], [81, 97], [97, 227]], columns=["start_1", "end_1"])

for i, row in df_0.iterrows():
    df_1.loc[(df_1.start_1 <= row.start_0) & (df_1.end_1 >= row.end_0), 'token'] = row.token

print(df_1)

Распечатывает следующее:

   start_1  end_1      token
0        0     17        NaN
1       17     29    aspirin
2       29     46        NaN
3       46     64  trazodone
4       64     76        NaN
5       76     81        NaN
6       81     97    placebo
7       97    227     haldol
0 голосов
/ 09 сентября 2018

Похоже, что вы действительно хотите сделать это сопоставить слова в df_0 с границами предложений, определенными в df_1. Для этого вы можете использовать pd.cut, стараясь включить все границы в df_1:

boundaries = np.hstack((df_1['start_1'], df_1['end_1'].iloc[-1]))
boundary_labels = df_1.index

df_0['sentence'] = pd.cut(df_0['start_0'], boundaries, labels=boundary_labels, right=False)

print(df_0)

   start_0  end_0      token sentence
0       20     27    aspirin        1
1       50     59  trazodone        3
2       81     88    placebo        6
3      121    127     haldol        7

Вы можете тривиально отобразить серию df_0['sentence'] обратно на df_1, поскольку значения идеально совпадают с df_1['token'] в желаемом выходе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...