Распределите значение поровну через NaN в пандах

У меня есть следующий фреймворк:

var_value 2016-07-01 05:10:00 809.0 2016-07-01 05:15:00 NaN 2016-07-01 05:20:00 NaN 2016-07-01 05:25:00 NaN 2016-07-01 05:30:00 NaN 2016-07-01 05:35:00 NaN 2016-07-01 05:40:00 NaN 2016-07-01 05:45:00 NaN 2016-07-01 05:50:00 NaN 2016-07-01 05:55:00 NaN 2016-07-01 06:00:00 NaN 2016-07-01 06:05:00 NaN 2016-07-01 06:10:00 185.0 2016-07-01 06:15:00 NaN 2016-07-01 06:20:00 NaN 2016-07-01 06:25:00 NaN 2016-07-01 06:30:00 NaN 2016-07-01 06:35:00 NaN 2016-07-01 06:40:00 NaN 2016-07-01 06:45:00 NaN 2016-07-01 06:50:00 NaN 2016-07-01 06:55:00 NaN 2016-07-01 07:00:00 NaN 2016-07-01 07:05:00 NaN 

Я хочу распределить 809.0 и 185.0 равномерно по всем строкам. Поэтому мой результирующий фреймворк должен выглядеть так:

  var_value 7/1/2016 5:10 67.42 7/1/2016 5:15 67.42 7/1/2016 5:20 67.42 7/1/2016 5:25 67.42 7/1/2016 5:30 67.42 7/1/2016 5:35 67.42 7/1/2016 5:40 67.42 7/1/2016 5:45 67.42 7/1/2016 5:50 67.42 7/1/2016 5:55 67.42 7/1/2016 6:00 67.42 7/1/2016 6:05 67.42 7/1/2016 6:10 15.42 7/1/2016 6:15 15.42 7/1/2016 6:20 15.42 7/1/2016 6:25 15.42 7/1/2016 6:30 15.42 7/1/2016 6:35 15.42 7/1/2016 6:40 15.42 7/1/2016 6:45 15.42 7/1/2016 6:50 15.42 7/1/2016 6:55 15.42 7/1/2016 7:00 15.42 7/1/2016 7:05 15.42 

Количество строк между известными значениями, которые должны быть распределены (так что NaN в этом случае) может отличаться. В этом случае это хорошо 11 неизвестных, но может быть 10 или 3 или 7 и т. Д.

Любая помощь в решении этого вопроса будет очень оценена.

Вы можете сначала ffill значения NaN а затем делить на len с помощью GroupBy.transform :

 df['var_value'] = df.var_value.ffill() df['var_value'] = df['var_value'] / df.groupby('var_value')['var_value'].transform(len) print (df) var_value 2016-07-01 05:10:00 67.416667 2016-07-01 05:15:00 67.416667 2016-07-01 05:20:00 67.416667 2016-07-01 05:25:00 67.416667 2016-07-01 05:30:00 67.416667 2016-07-01 05:35:00 67.416667 2016-07-01 05:40:00 67.416667 2016-07-01 05:45:00 67.416667 2016-07-01 05:50:00 67.416667 2016-07-01 05:55:00 67.416667 2016-07-01 06:00:00 67.416667 2016-07-01 06:05:00 67.416667 2016-07-01 06:10:00 15.416667 2016-07-01 06:15:00 15.416667 2016-07-01 06:20:00 15.416667 2016-07-01 06:25:00 15.416667 2016-07-01 06:30:00 15.416667 2016-07-01 06:35:00 15.416667 2016-07-01 06:40:00 15.416667 2016-07-01 06:45:00 15.416667 2016-07-01 06:50:00 15.416667 2016-07-01 06:55:00 15.416667 2016-07-01 07:00:00 15.416667 2016-07-01 07:05:00 15.416667 

Сравнение решений:

len(df)=24 :

 In [18]: %timeit (jez(df)) 1000 loops, best of 3: 1.18 ms per loop In [19]: %timeit (pir(df1)) 100 loops, best of 3: 2.92 ms per loop 

len(df)=24k :

 In [21]: %timeit (jez(df)) 100 loops, best of 3: 7.49 ms per loop In [22]: %timeit (pir(df1)) 1 loop, best of 3: 590 ms per loop 

Код для таймингов:

 #if need comapre 24k #df = pd.concat([df]*1000).reset_index(drop=True) df1 = df.copy() def jez(df): df['var_value'] = df.var_value.ffill() df['var_value'] = df['var_value'] / df.groupby('var_value')['var_value'].transform(len) return df def pir(df): df = df.fillna(0).groupby(df.var_value.notnull().cumsum()).transform(lambda x: x.mean()) return df print (jez(df)) print (pir(df1)) 
 df.fillna(0).groupby(df.notnull().cumsum()).transform(lambda x: x.mean()) 2016-07-01 05:10:00 67.416667 2016-07-01 05:15:00 67.416667 2016-07-01 05:20:00 67.416667 2016-07-01 05:25:00 67.416667 2016-07-01 05:30:00 67.416667 2016-07-01 05:35:00 67.416667 2016-07-01 05:40:00 67.416667 2016-07-01 05:45:00 67.416667 2016-07-01 05:50:00 67.416667 2016-07-01 05:55:00 67.416667 2016-07-01 06:00:00 67.416667 2016-07-01 06:05:00 67.416667 2016-07-01 06:10:00 15.416667 2016-07-01 06:15:00 15.416667 2016-07-01 06:20:00 15.416667 2016-07-01 06:25:00 15.416667 2016-07-01 06:30:00 15.416667 2016-07-01 06:35:00 15.416667 2016-07-01 06:40:00 15.416667 2016-07-01 06:45:00 15.416667 2016-07-01 06:50:00 15.416667 2016-07-01 06:55:00 15.416667 2016-07-01 07:00:00 15.416667 2016-07-01 07:05:00 15.416667 Name: var_value, dtype: float64 

объяснение

  • df.notnull().cumsum() создает серию, которую я могу groupby с помощью

  • df.fillna(0) гарантирует, что NaN s включены как 0 когда я вычисляю mean

  • transform(lambda x: x.mean()) вычисляет lambda функцию для каждого элемента в группе.

df.notnull.cumsum()

 2016-07-01 05:10:00 1 2016-07-01 05:15:00 1 2016-07-01 05:20:00 1 2016-07-01 05:25:00 1 2016-07-01 05:30:00 1 2016-07-01 05:35:00 1 2016-07-01 05:40:00 1 2016-07-01 05:45:00 1 2016-07-01 05:50:00 1 2016-07-01 05:55:00 1 2016-07-01 06:00:00 1 2016-07-01 06:05:00 1 2016-07-01 06:10:00 2 2016-07-01 06:15:00 2 2016-07-01 06:20:00 2 2016-07-01 06:25:00 2 2016-07-01 06:30:00 2 2016-07-01 06:35:00 2 2016-07-01 06:40:00 2 2016-07-01 06:45:00 2 2016-07-01 06:50:00 2 2016-07-01 06:55:00 2 2016-07-01 07:00:00 2 2016-07-01 07:05:00 2 Name: var_value, dtype: int64