在大熊猫的NaN中平均分配价值

时间:2016-07-13 14:24:40

标签: python pandas

我有以下数据框:

                     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等等。

非常感谢任何有关解决此问题的帮助。

2 个答案:

答案 0 :(得分:2)

您可以先ffill NaN个值,然后用GroupBy.transform除以len

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))

答案 1 :(得分:2)

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

  • 时,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