Looking up multiple dictionary keys in a Pandas Dataframe & return multiple values for matches

可紊 提交于 2020-01-01 06:40:08

问题


First time posting so apologies in advance if my formatting is off.

Here's my issue:

I've created a Pandas dataframe which contains multiple rows of text:

d = {'keywords' :['cheap shoes', 'luxury shoes', 'cheap hiking shoes']}
keywords = pd.DataFrame(d,columns=['keywords'])
In [7]: keywords
Out[7]:
        keywords
0  cheap shoes
1  luxury shoes
2  cheap hiking shoes

Now I have a dictionary that contains the following keys / values:

labels = {'cheap' : 'budget', 'luxury' : 'expensive', 'hiking' : 'sport'}

What I would like to do is find out whether a key in the dictionary exist in the dataframe, and if so, return the appropriate value

I was able to somewhat get there using the following:

for k,v in labels.items():
   keywords['Labels'] = np.where(keywords['keywords'].str.contains(k),v,'No Match')

However, the output is missing the first two keys and is only catching the last "hiking" key

    keywords            Labels
0   cheap shoes         No Match
1   luxury shoes        No Match
2   cheap hiking shoes  sport

Additionally, I'd also like to know if there's a way to catch multiple values in the dictionary separated by | , so the ideal output would look like this

    keywords            Labels
0   cheap shoes         budget
1   luxury shoes        expensive
2   cheap hiking shoes  budget | sport

Any help or guidance is much appreciated.

Cheers


回答1:


It's certainly possible. Here is one way.

d = {'keywords': ['cheap shoes', 'luxury shoes', 'cheap hiking shoes', 'nothing']}

keywords = pd.DataFrame(d,columns=['keywords'])

labels = {'cheap': 'budget', 'luxury': 'expensive', 'hiking': 'sport'}

df = pd.DataFrame(d)

def matcher(k):
    x = (i for i in labels if i in k)
    return ' | '.join(map(labels.get, x))

df['values'] = df['keywords'].map(matcher)

#              keywords          values
# 0         cheap shoes          budget
# 1        luxury shoes       expensive
# 2  cheap hiking shoes  budget | sport
# 3             nothing                



回答2:


You can use "|".join(labels.keys()) to get a pattern to be used by re.findall().

import pandas as pd
import re

d = {'keywords' :['cheap shoes', 'luxury shoes', 'cheap hiking shoes']}
keywords = pd.DataFrame(d,columns=['keywords'])
labels = {'cheap' : 'budget', 'luxury' : 'expensive', 'hiking' : 'sport'}
pattern = "|".join(labels.keys())

def f(s):
    return "|".join(labels[word] for word in re.findall(pattern, s))

keywords.keywords.map(f)



回答3:


Sticking with your approach, you could do e.g.

arr = np.array([np.where(keywords['keywords'].str.contains(k), v, 'No Match') for k, v in labels.items()]).T
keywords["Labels"] = ["|".join(set(item[ind if ind.sum() == ind.shape[0] else ~ind])) for item, ind in zip(arr, (arr == "No Match"))]

Out[97]: 
             keywords        Labels
0         cheap shoes        budget
1        luxury shoes     expensive
2  cheap hiking shoes  sport|budget



回答4:


I like the idea of using replace first then finding the values.

keywords.assign(
    values=
    keywords.keywords.replace(labels, regex=True)
            .str.findall(f'({"|".join(labels.values())})')
            .str.join(' | ')
)

             keywords          values
0         cheap shoes          budget
1        luxury shoes       expensive
2  cheap hiking shoes  budget | sport



回答5:


You could split the strings into separate columns, then stack into a multi index, so that you can map, the labels dictionary to the values. Then groupby the initial index, and concatenate the strings that belong to each index

keywords['Labels'] = keywords.keywords.str.split(expand=True).stack()\
                     .map(labels).groupby(level=0)\
                     .apply(lambda x: x.str.cat(sep=' | '))



            keywords          Labels
0         cheap shoes          budget
1        luxury shoes       expensive
2  cheap hiking shoes  budget | sport


来源:https://stackoverflow.com/questions/49121526/looking-up-multiple-dictionary-keys-in-a-pandas-dataframe-return-multiple-valu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!