Найти первое вхождение подстроки из словаря подстрок в каждом значении серии pandas и вставить соответствующее значение словаря - PullRequest
0 голосов
/ 13 февраля 2020

Предположим, у меня есть следующий словарь:

myDict= {'is':'A', 'th':'B', 'ro':'C'}

и следующий Pandas фрейм данных с одним столбцом строк (без индекса):

checkColumn

This is the first row
Here is the second row
Row three is here
And another row is here

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

checkColumn                         labelAssignment

This is the first row               B
Here is the second row              A
Row three is here                   C
And another row is here             B

Несколько параметров:
- В каждой строке может отображаться несколько ключей. Например, в третьем ряду отображаются все три клавиши, но им назначается C, поскольку «ro» появляется первым.
- подстроки могут быть частями слов, поэтому разбейте строку на отдельные слова и проверьте их не будет работать.
- мне нужно, чтобы он был без учета регистра, так что 'ro' соответствует 'Row'.
- Если ключ не найден, можно указать np.nan или пустую строку .

Почти все ответы по SO, которые я нашел до сих пор, касаются либо (a) нахождения первого значения ряда, но не первой подстроки из каждого значения этого ряда, либо (b ) первое вхождение подстроки в строке без применения ее к pandas кадру данных. Например, этот ответ показывает, как проверить, содержится ли ключ в словаре в строке, но поскольку это pandas, я не должен использовать циклы for, а понимание списка возвращает список, который я не хочу ... Я хочу вернуть само значение.

Псевдокод, который я имею в виду, использует np.where:

df['labelAssignment'] = np.where(check for first occurrence of myDict key in df.checkColumn, corresponding value from myDict, '')

Но как мне сформировать синтаксис этого оператора np.where?

Ответы [ 3 ]

1 голос
/ 13 февраля 2020

Для этой логики c вам нужно применить построчно. Начните с поиска checkColumn по ключу dict, затем выполните сортировку по индексу поиска, чтобы найти самое раннее появление. Убедитесь, что он не отображается вообще:

def label_for_check(row):
    check = row['checkColumn'] or ''
    index, lookup = sorted([(check.lower().find(k.lower()), k) for k in myDict.keys()])[0]
    return myDict[lookup] if index >= 0 else np.nan

df['labelAssignment'] = df.apply(label_for_check, axis=1)
               checkColumn labelAssignment
0    This is the first row               B
1   Here is the second row               A
2        Row three is here               C
3  And another row is here               B
4               nothing...             NaN
1 голос
/ 13 февраля 2020

В зависимости от системы вы можете использовать OrderedDict, чтобы гарантировать заданный порядок словаря. Но вы можете сделать что-то вроде этого:

(df.checkColumn
   .str.lower()
   .str.extract("({:})".format('|'.join(myDict.keys())) )[0]
   .map(myDict)
)

Вывод:

0    B
1    A
2    C
3    B
Name: 0, dtype: object
0 голосов
/ 13 февраля 2020
import pandas as pd
import re
myDict= {'is':'A', 'th':'B', 'ro':'C'}
rows=['This is the first row','Here is the second row','Row three is here','And another row is here']

df=pd.DataFrame(rows,columns=['checkColumn'])

df

Первый вывод

    checkColumn
0   This is the first row
1   Here is the second row
2   Row three is here
3   And another row is here

Создание одной функции

temp=[]
def checkrows(x):
    list1 = myDict.keys()
    temp=[]
    for item in list1:
        pattern=item
        match=re.search(pattern,x.lower())
        temp.append([match.start(),match.end()])

    temp.sort()
    return x[temp[0][0]:temp[0][1]].lower()

result=df.checkColumn.apply(lambda x: checkrows(x))

df['Label Assignment']=[myDict[item] for item in result]

df

Окончательный вывод

    checkColumn             Label Assignment
0   This is the first row        B
1   Here is the second row       A
2   Row three is here            C
3   And another row is here      B

Примечание. Сократить этот код можно несколькими способами.

Спасибо

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