Поиск нескольких подстрок в столбце строк и возврат категории подстрок - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть два кадра данных следующим образом:

df1 = pd.DataFrame({"id":["01", "02", "03", "04", "05", "06"],
                    "string":["This is a cat",
                              "That is a dog",
                              "Those are birds",
                              "These are bats",
                              "I drink coffee",
                              "I bought tea"]})

df2 = pd.DataFrame({"category":[1, 1, 2, 2, 3, 3],
                    "keywords":["cat", "dog", "birds", "bats", "coffee", "tea"]})

Мои кадры данных выглядят следующим образом

df1:

id   string
01   This is a cat
02   That is a dog
03   Those are birds
04   These are bats
05   I drink coffee
06   I bought tea

df2:

category   keywords
1          cat
1          dog
2          birds
2          bats
3          coffee
3          tea

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

id   string             category
01   This is a cat         1
02   That is a dog         1
03   Those are birds       2
04   These are bats        2
05   I drink coffee        3
06   I bought tea          3

Я могу подумать о циклическом переборе ключевых слов по одному и сканировании строки по одному, но это недостаточно эффективно, если объем данных увеличивается.Могу ли я получить ваши предложения, как улучшить?Спасибо.

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

Используйте понимание списка с помощью split и сопоставьте по словарю, созданному df2:

d = dict(zip(df2['keywords'], df2['category']))
df1['cat'] = [next((d[y] for y in x.split() if y in d), None) for x in df1['string']]

print (df1)
   id           string  cat
0  01    This is a cat  1.0
1  02    That is a dog  1.0
2  03  Those are birds  2.0
3  04   These are bats  2.0
4  05   I drink coffee  3.0
5  06    I bought thea  NaN
0 голосов
/ 18 декабря 2018

Еще одно простое для понимания решение df1['string']:

# create a dictionary with keyword->category pairs
cats = dict(zip(df2.keywords, df2.category))

def categorize(s):
    for cat in cats.keys():
        if cat in s:
            return cats[cat]
    # return 0 in case nothing is found
    return 0

df1['category'] = df1['string'].map(lambda x: categorize(x))

print(df1)

   id           string  category
0  01    This is a cat         1
1  02    That is a dog         1
2  03  Those are birds         2
3  04   These are bats         2
4  05   I drink coffee         3
5  06     I bought tea         3
0 голосов
/ 18 декабря 2018
# Modified your data a bit.
df1 = pd.DataFrame({"id":["01", "02", "03", "04", "05", "06", "07"],
                    "string":["This is a cat",
                              "That is a dog",
                              "Those are birds",
                              "These are bats",
                              "I drink coffee",
                              "I bought tea", 
                              "This won't match squat"]})

Вы можете использовать понимание списка, включающее next с аргументом по умолчанию.

df1['category'] = [
    next((c for c, k in df2.values if k in s), None) for s in df1['string']] 

df1
   id                  string  category
0  01           This is a cat       1.0
1  02           That is a dog       1.0
2  03         Those are birds       2.0
3  04          These are bats       2.0
4  05          I drink coffee       3.0
5  06            I bought tea       3.0
6  07  This won't match squat       NaN

Вы не можете избежать сложности O (N 2 ), но это должнобыть достаточно производительным, поскольку он не всегда должен перебирать каждую строку во внутреннем цикле (если не в худшем случае).

Обратите внимание, что в настоящее время поддерживается только сопоставление подстрок (не сопоставление на основе регулярных выражений, хотя снебольшая модификация, которую можно сделать).

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