2015-12-12 8 views
3

у меня есть большой набор данных формы:Панды заменить нан со средним значением для данной группировки

period_id gic_subindustry_id operating_mgn_fym5 operating_mgn_fym4 317  201509   25101010   13.348150   11.745965 
682  201509   20101010   10.228725   10.473917 
903  201509   20101010   NaN     17.700966 
1057  201509   50101010   27.858305   28.378040 
1222  201509   25502020   15.598956   11.658813 
2195  201508   25502020   27.688324   22.969760 
2439  201508   45202020   NaN     27.145216 
2946  201508   45102020   17.956425   18.327724 

На практике, у меня есть тысячи значений за каждый год уходящие 25 лет, и несколько (10+).

Я пытаюсь заменить значения NaN средним/средним значением gic_industry_id за этот период времени.

Я пытался что-то вдоль линий

df.fillna (df.groupby ('period_id', 'gic_subindustry_id'). Преобразование ('среднее')), , но это, казалось, мучительно медленно (я остановили его через несколько минут).

Мне пришло в голову, что причина, по которой она может быть медленной, связана с пересчетом среднего значения для каждого обнаруженного NaN. Чтобы обойти это, я подумал, что вычисление среднего значения в каждом периоде_id, а затем замена/отображение каждого NaN с использованием этого может быть значительно быстрее.

means = df.groupby(['period_id', 'gic_subindustry_id']).apply(lambda x:x.mean()) 

Выход:

       operating_mgn_fym5 operating_mgn_fym4 operating_mgn_fym3 operating_mgn_fym2 
period_id gic_subindustry_id            
201509 45202030   1.622685 0.754661 0.755324 321.295665 
      45203010   1.447686 0.226571 0.334280 12.564398 
      45203015   0.733524 0.257581 0.345450 27.659407 
      45203020   1.322349 0.655481 0.468740 19.823722 
      45203030   1.461916 1.181407 1.487330 16.598534 
      45301010   2.074954 0.981030 0.841125 29.423161 
      45301020   2.621158 1.235087 1.550252 82.717147 

И в самом деле, это гораздо быстрее (30 - 60 секунд).

Однако я изо всех сил пытаюсь понять, как нанести NaNs на эти средства. И действительно, является ли это «правильным» способом выполнения этого сопоставления? Скорость на самом деле не имеет первостепенной важности, но < 60 секунд было бы неплохо.

ответ

3

Вы можете использовать fillna используя результат группы по-, при условии, что dataframes имеют ту же структуру (дается as_index=False):

df.fillna(df.groupby(['period_id', 'gic_subindustry_id'], as_index=False).mean()) 

#In [60]: df 
#Out[60]: 
# period_id gic_subindustry_id operating_mgn_fym5 operating_mgn_fym4 
#0  201508   25502020   27.688324   22.969760 
#1  201508   45102020   17.956425   18.327724 
#2  201508   45202020     NaN   27.145216 
#3  201509   20101010   10.228725   14.087442 
#4  201509   25101010   13.348150   11.745965 
#5  201509   25502020   15.598956   11.658813 
#6  201509   50101010   27.858305   28.378040 
#7  201508   45102020   17.956425   18.327724 
Смежные вопросы