2015-04-28 2 views
3

У меня есть рабочий код, который классифицирует данные на основе правил внутри словаря списка. Я хочу знать, можно ли сделать код более эффективным, избавляясь от вложенных циклов, используя понимание списка/словаря или .values ​​().Python 3 эффективно итерации по словарю списка

import pandas as pd 


df=pd.DataFrame({'Animals': [ 'Python', 'Anaconda', 'Viper', 'Cardinal', 
       'Trout', 'Robin', 'Bass', 'Salmon', 'Turkey', 'Chicken'], 
       'Noise': ['Hiss','SSS','Hisss','Chirp','Splash','Chirp', 
       'Gulp','Splash','Gobble','Cluck'], 
       }) 


snakenoise =['Hiss','SSS','Hisss', 'Wissss', 'tseee'] 
birdnoise =['Chirp', 'squeak', 'Cluck', 'Gobble'] 
fishnoise =['Splash', 'Gulp', 'Swim'] 


AnimalDex = {'Snake':['0', 'slither',snakenoise], 
       'Bird':['2','fly', birdnoise], 
       'Fish':['0','swim',fishnoise], 
       } 

df['movement'] = '' 

for key, value in AnimalDex.items(): 
    for i in range(len(AnimalDex[key][2])): 
     df.loc[df.Noise.str.contains(AnimalDex[key][2][i]),'movement'] = AnimalDex[key][1] 

print (df) 

Вот выход

Animals Noise movement 
0 Python Hiss slither 
1 Anaconda  SSS slither 
2  Viper Hisss slither 
3 Cardinal Chirp  fly 
4  Trout Splash  swim 
5  Robin Chirp  fly 
6  Bass Gulp  swim 
7 Salmon Splash  swim 
8 Turkey Gobble  fly 
9 Chicken Cluck  fly 
+0

С помощью всего лишь десяти записей вы не должны беспокоиться об эффективности. –

+2

Вы понимаете, что переписка по спискам и словам делает то же самое, что и петли? Они не более или менее эффективны, и иногда их может быть труднее читать. – nathancahill

+0

@Tichodroma Это просто образец псевдокода большего файла. Я не размещаю какой-то большой dict или код, чтобы просто заполнить пробел – ccsv

ответ

0

Если вы просто использовать значения вместо ключей и индексов, вы можете реально упростить цикл.

for animal in AnimalDex.values(): 
    for value in animal[2]: 
     df.loc[df.Noise.str.contains(value),'movement'] = animal[1] 
+0

Я думаю, что нет хорошего способа обойти этот цикл 'for'. :( – ccsv

0

Эффективность не приходит от перезаписи петли как постижения, так как постижения в основном обеспечивают более хороший синтаксис для петель. Скорее, эффективность поиска структур данных важна. Проблема в том, что df.Noise.str.contains(AnimalDex[key][2][i]) выполняет сопоставление грубой силы.

Если ваша цель состоит в том, чтобы объединить движения, определенные в AnimalDex в df, вступив в соответствии с шумом, то он платит, чтобы построить словарь, который отображает шумы движения:

noise_to_movement = {} 
for order in AnimalDex.values(): 
    for noise in order[2]: 
     noise_to_movement[noise] = order[1] 

Для сравнения, здесь другой способ построения noise_to_movement, используя непонятные постижения:

import itertools 

noise_to_movement = dict(itertools.chain(*[list(
    itertools.product(order[2], [order[1]])) for order in AnimalDex.values() 
])) 

в любом случае, как только словарь построен, установка 'movement' столбца становится тривиальным поиском:

df['movement'] = list(noise_to_movement[n] for n in df.Noise) 
0

Чтобы действительно улучшить производительность, вы не должны итерировать через словарь. Вместо этого сделайте pandas.DataFrame из этих данных и присоединитесь к двум DataFrames.

import pandas as pd 

df = pd.DataFrame({'Animals': [ 'Python', 'Anaconda', 'Viper', 'Cardinal', 
        'Trout', 'Robin', 'Bass', 'Salmon', 'Turkey', 'Chicken'], 
        'Noise': ['Hiss','SSS','Hisss','Chirp','Splash','Chirp', 
        'Gulp','Splash','Gobble','Cluck']}) 

snakenoise =['Hiss','SSS','Hisss', 'Wissss', 'tseee'] 
birdnoise =['Chirp', 'squeak', 'Cluck', 'Gobble'] 
fishnoise =['Splash', 'Gulp', 'Swim'] 

noises = [(snakenoise, 'Snake', '0', 'slither'), 
      (birdnoise, 'Bird', '2', 'fly'), 
      (fishnoise, 'Fish', '0', 'swim')] 

animal_dex = {'Animal Type': [], 
       'Whatever': [], 
       'Movement': [], 
       'Noise': []} 

for noise in noises: 
    animal_dex['Noise'] += noise[0] 
    animal_dex['Animal Type'] += map(lambda x: noise[1], noise[0]) 
    animal_dex['Whatever'] += map(lambda x: noise[2], noise[0]) 
    animal_dex['Movement'] += map(lambda x: noise[3], noise[0]) 

df1 = pd.DataFrame(animal_dex) 

df = df.merge(df1, on='Noise') 
df 
    Animals Noise Animal Type Movement Whatever 
0 Python Hiss  Snake slither  0 
1 Anaconda  SSS  Snake slither  0 
2  Viper Hisss  Snake slither  0 
3 Cardinal Chirp  Bird  fly  2 
4  Robin Chirp  Bird  fly  2 
5  Trout Splash  Fish  swim  0 
6 Salmon Splash  Fish  swim  0 
7  Bass Gulp  Fish  swim  0 
8 Turkey Gobble  Bird  fly  2 
9 Chicken Cluck  Bird  fly  2 
Смежные вопросы