Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find element in list in dataframe

I have a dataframe "df1":

adj           response

beautiful    ["She's a beautiful girl/woman, and also a good teacher."]
good         ["She's a beautiful girl/woman, and also a good teacher."]
hideous      ["This city is hideous, let's move to the countryside."]

And here's the object list:

object=["girl","teacher","city","countryside","woman"]

Code:

df1['response_split']=df1['response'].str.split(",")

After I split it, the dataframe will be like this:

adj           response_split

beautiful    ["She's a beautiful girl/woman", " and also a good teacher."]
good         ["She's a beautiful girl/woman", " and also a good teacher."]
hideous      ["This city is hideous", " let's move to the countryside."]

I want to add another column "response_object", if they find the adj in response, they find its object from list object: expected result

adj           response_split                                               response_object

beautiful    ["She's a beautiful girl/woman", " and also a good teacher."]        girl
beautiful    ["She's a beautiful girl/woman", " and also a good teacher."]        woman
good         ["She's a beautiful girl/woman", " and also a good teacher."]        teacher
hideous      ["This city is hideous", " let's move to the countryside."]          city

code:

for i in df1['response_split']:
    if df1['adj'] in i:
        if any(x in i and x in object):
            match = list(filter(lambda x: x in i, object))
            df1['response_object']=match

It prints ValueError

like image 223
Ching Avatar asked Oct 15 '22 13:10

Ching


1 Answers

First object is valid python builtins (code word), so better dont use it for variable, here is changed to L:

L=["girl","teacher","city","countryside","woman"]

Then zip splitted column with adj, loop by tuples, loop by values in L and match if both match with in and and:

df1['response_split']=df1['response'].str.split(",")
L1 = [(a, b, o) for a, b in zip(df1['adj'], df1['response_split']) 
                for r in b 
                for o in L 
                if (o in r) and (a in r)]

What should be rewrite to loops:

df1['response_split']=df1['response'].str.split(",")

L1 = []
for a, b in zip(df1['adj'], df1['response_split']):
    for r in b:
        for o in L:
            if (o in r) and (a in r):
                L1.append((a, b, o))

Last create DataFrame constructor:

df2 = pd.DataFrame(L1, columns=['adj','response_split','response_object'])
print (df2)
         adj                                     response_split  \
0  beautiful  [She's a beautiful girl/woman,  and also a goo...   
1  beautiful  [She's a beautiful girl/woman,  and also a goo...   
2       good  [She's a beautiful girl/woman,  and also a goo...   
3    hideous  [This city is hideous,  let's move to the coun...   

  response_object  
0            girl  
1           woman  
2         teacher  
3            city  
like image 189
jezrael Avatar answered Oct 19 '22 02:10

jezrael