2016-09-28 4 views
2

У меня есть уникальный вопрос, и я прежде всего надеюсь найти способы немного ускорить этот код. У меня есть набор строк, хранящихся в dataframe, каждый из которых имеет несколько названий в нем, и я знаю, что количество имен до этого шага, например, так:Поиск многих строк для многих словарных клавиш, быстро

print df 

description      num_people  people  
'Harry ran with sally'    2    []   
'Joe was swinging with sally'   2    [] 
'Lola Dances alone'     1    [] 

Я использую словарь с ключами, которые я ищу, чтобы найти в описании, например:

my_dict={'Harry':'1283','Joe':'1828','Sally':'1298', 'Cupid':'1982'} 

, а затем с помощью iterrows искать каждую строку для спичек, как так:

for index, row in df.iterrows(): 
    row.people=[key for key in my_dict if re.findall(key,row.desciption)] 

и при запуске он заканчивает с

print df 

description      num_people  people  
'Harry ran with sally'    2    ['Harry','Sally']   
'Joe was swinging with sally'   2    ['Joe','Sally'] 
'Lola Dances alone'     1    ['Lola'] 

Проблема, которую я вижу, что этот код все еще достаточно медленно, чтобы получить работу, и у меня есть большое количество описаний и над 1000 ключами. Есть ли более быстрый способ выполнить эту операцию, например, используя количество найденных людей?

ответ

2

Быстрее Решение:

#strip ' in start and end of text, create lists from words 
splited = df.description.str.strip("'").str.split() 
#filtering 
df['people'] = splited.apply(lambda x: [i for i in x if i in my_dict.keys()]) 
print (df) 
        description num_people   people 
0   'Harry ran with Sally'   2 [Harry, Sally] 
1 'Joe was swinging with Sally'   2 [Joe, Sally] 
2   'Lola Dances alone'   1   [Lola] 

тайминги:

#[30000 rows x 3 columns] 
In [198]: %timeit (orig(my_dict, df)) 
1 loop, best of 3: 3.63 s per loop 

In [199]: %timeit (new(my_dict, df1)) 
10 loops, best of 3: 78.2 ms per loop 
df['people'] = [[],[],[]] 
df = pd.concat([df]*10000).reset_index(drop=True) 
df1 = df.copy() 

my_dict={'Harry':'1283','Joe':'1828','Sally':'1298', 'Lola':'1982'} 

def orig(my_dict, df): 
    for index, row in df.iterrows(): 
     df.at[index, 'people']=[key for key in my_dict if re.findall(key,row.description)] 
    return (df) 


def new(my_dict, df): 
    df.description = df.description.str.strip("'") 
    splited = df.description.str.split() 
    df.people = splited.apply(lambda x: [i for i in x if i in my_dict.keys()]) 
    return (df) 


print (orig(my_dict, df)) 
print (new(my_dict, df1)) 
Смежные вопросы