Python 仅取大熊猫中两个连续值的平均值

Python 仅取大熊猫中两个连续值的平均值,python,pandas,Python,Pandas,我有一个非均匀分布的数据帧,比如 2013-05-16 17:33:30 485.75 NaN NaN 2013-05-16 17:34:00 479.16 NaN NaN 2013-05-16 17:35:30 NaN 429.90 NaN 2013-05-16 17:36:00 NaN 433.39 NaN 2013-05-16 17:37:30 NaN NaN 415.94 2013-05-16 17

我有一个非均匀分布的数据帧,比如

2013-05-16 17:33:30  485.75     NaN     NaN
2013-05-16 17:34:00  479.16     NaN     NaN
2013-05-16 17:35:30     NaN  429.90     NaN
2013-05-16 17:36:00     NaN  433.39     NaN
2013-05-16 17:37:30     NaN     NaN  415.94
2013-05-16 17:38:00     NaN     NaN  401.59
2013-05-16 17:49:30  432.23     NaN     NaN
2013-05-16 17:51:00     NaN  424.08     NaN
2013-05-16 17:52:30     NaN     NaN  411.67
2013-05-16 18:01:30  471.01     NaN     NaN
2013-05-16 18:02:00  474.11     NaN     NaN
2013-05-16 18:03:30     NaN  440.76     NaN
2013-05-16 18:04:00     NaN  438.82     NaN
2013-05-16 18:17:30  469.46     NaN     NaN
2013-05-16 18:18:00  460.93     NaN     NaN
我可以分别对待每一列。因此,对于每一列,我可以有一个、两个、三个甚至四个连续的值,这些值由
nan
s包围。我想做的是一次只取两个连续的行,用它们的平均值替换它们的值,用它们的平均值替换它们的索引。因此,我将用值和索引的平均值替换任意两行连续的值,只替换一行。因此,上面的例子将成为

2013-05-16 17:33:45  482.45     NaN     NaN
2013-05-16 17:35:45     NaN  431.69     NaN
2013-05-16 17:37:45     NaN     NaN  408.76
2013-05-16 17:49:30  432.23     NaN     NaN
2013-05-16 17:51:00     NaN  424.08     NaN
2013-05-16 17:52:30     NaN     NaN  411.67
2013-05-16 18:01:45  472.56     NaN     NaN
2013-05-16 18:03:45     NaN  439.78     NaN
2013-05-16 18:17:45  465.19     NaN     NaN
因此,将对连续的值进行平均,只保留一个值的行。我尝试过类似于
df.resample('30s')。resample('2min')
(df+df.shift(1))/2
,但到目前为止没有成功。有什么想法吗

注意:对于每一行,只有一列有值,其他列总是
NaN

您可以首先
datetimeindex
Unix time
,然后从
index
创建新列,获取每列的
mean
。通过以下方式将Unix时间最后转换为日期时间:

说明:

首先,您需要从值创建组,其中列包含数字。您需要使用值
0
,因为有时函数返回后的第一个值
NaN
。在此示例中,它仅为列
a
。但在实际数据中,它也可以位于列
b
和列
c

df1 = pd.DataFrame( {'isnull': df.a.isnull()})
df1['diff'] = df1['isnull'].diff()
df1['cumsum'] = df1['diff'].cumsum().fillna(0)
print df1
   isnull   diff  cumsum
0   False    NaN     0.0
1   False  False     0.0
2    True   True     1.0
3    True  False     1.0
4    True  False     1.0
5    True  False     1.0
6   False   True     2.0
7    True   True     3.0
8    True  False     3.0
9   False   True     4.0
10  False  False     4.0
11   True   True     5.0
12   True  False     5.0
13  False   True     6.0
14  False  False     6.0
然后,您可以按此分组并聚合。因为您丢失了
索引
,所以我创建了新的列
索引
,它也是聚合的。然后,我从列
索引
,只过滤一列
a
b
c
,因为我通过这个新索引聚合了所有数据帧

print df.groupby(df.a.isnull().cumsum().fillna(0)).mean()
        index        a       b       c
a                                     
0  1368725625  482.455     NaN     NaN
1  1368725730      NaN  429.90     NaN
2  1368725760      NaN  433.39     NaN
3  1368725850      NaN     NaN  415.94
4  1368726225  432.230     NaN  401.59
5  1368726660      NaN  424.08     NaN
6  1368727120  472.560     NaN  411.67
7  1368727410      NaN  440.76     NaN
8  1368727990  465.195  438.82     NaN
如果您需要更自动的aproach,请使用:

#convert to unix time (need integers from datetime for mean)
df.index = df.index.astype(np.int64) // 10**9
#create column index from df.index
df = df.reset_index()
#print df

dfs = []
#select all columns without first index column
for col in df.columns[1:]:
    dfs.append(df.groupby(df[col].isnull().diff().cumsum().fillna(0)).mean().set_index('index')[[col]])
df = pd.concat(dfs, axis=1)

#drop rows with all NaN
df = df.dropna(how='all').rename_axis(None)  
#convert unix time to datetime
df.index = pd.to_datetime(df.index, unit='s')
print df
                           a        b        c
2013-05-16 17:33:45  482.455      NaN      NaN
2013-05-16 17:35:45      NaN  431.645      NaN
2013-05-16 17:37:45      NaN      NaN  408.765
2013-05-16 17:49:30  432.230      NaN      NaN
2013-05-16 17:51:00      NaN  424.080      NaN
2013-05-16 17:52:30      NaN      NaN  411.670
2013-05-16 18:01:45  472.560      NaN      NaN
2013-05-16 18:03:45      NaN  439.790      NaN
2013-05-16 18:17:45  465.195      NaN      NaN

我想知道是否有一种方法可以避免手动设置每一列,并使其更加自动化。答案不错。答案已编辑,请检查。抱歉耽搁了。谢谢,您的编辑正是我40分钟前实现您的答案时所做的:)我指的是一种不必循环浏览专栏的方式(抱歉,我不是很清楚)。我认为在
数据帧列表中添加
dfs
的方法很好地实现为
concat
函数中的输入。
df1 = pd.DataFrame( {'isnull': df.a.isnull()})
df1['diff'] = df1['isnull'].diff()
df1['cumsum'] = df1['diff'].cumsum().fillna(0)
print df1
   isnull   diff  cumsum
0   False    NaN     0.0
1   False  False     0.0
2    True   True     1.0
3    True  False     1.0
4    True  False     1.0
5    True  False     1.0
6   False   True     2.0
7    True   True     3.0
8    True  False     3.0
9   False   True     4.0
10  False  False     4.0
11   True   True     5.0
12   True  False     5.0
13  False   True     6.0
14  False  False     6.0
print df.groupby(df.a.isnull().cumsum().fillna(0)).mean()
        index        a       b       c
a                                     
0  1368725625  482.455     NaN     NaN
1  1368725730      NaN  429.90     NaN
2  1368725760      NaN  433.39     NaN
3  1368725850      NaN     NaN  415.94
4  1368726225  432.230     NaN  401.59
5  1368726660      NaN  424.08     NaN
6  1368727120  472.560     NaN  411.67
7  1368727410      NaN  440.76     NaN
8  1368727990  465.195  438.82     NaN
print df.groupby(df.a.isnull().cumsum().fillna(0)).mean().set_index('index')
                  a       b       c
index                              
1368725625  482.455     NaN     NaN
1368725730      NaN  429.90     NaN
1368725760      NaN  433.39     NaN
1368725850      NaN     NaN  415.94
1368726225  432.230     NaN  401.59
1368726660      NaN  424.08     NaN
1368727120  472.560     NaN  411.67
1368727410      NaN  440.76     NaN
1368727990  465.195  438.82     NaN
print df.groupby(df.a.isnull().cumsum().fillna(0)).mean().set_index('index')[['a']]
                 a
index              
1368725625  482.455
1368725730      NaN
1368725760      NaN
1368725850      NaN
1368726225  432.230
1368726660      NaN
1368727120  472.560
1368727410      NaN
1368727990  465.195
#convert to unix time (need integers from datetime for mean)
df.index = df.index.astype(np.int64) // 10**9
#create column index from df.index
df = df.reset_index()
#print df

dfs = []
#select all columns without first index column
for col in df.columns[1:]:
    dfs.append(df.groupby(df[col].isnull().diff().cumsum().fillna(0)).mean().set_index('index')[[col]])
df = pd.concat(dfs, axis=1)

#drop rows with all NaN
df = df.dropna(how='all').rename_axis(None)  
#convert unix time to datetime
df.index = pd.to_datetime(df.index, unit='s')
print df
                           a        b        c
2013-05-16 17:33:45  482.455      NaN      NaN
2013-05-16 17:35:45      NaN  431.645      NaN
2013-05-16 17:37:45      NaN      NaN  408.765
2013-05-16 17:49:30  432.230      NaN      NaN
2013-05-16 17:51:00      NaN  424.080      NaN
2013-05-16 17:52:30      NaN      NaN  411.670
2013-05-16 18:01:45  472.560      NaN      NaN
2013-05-16 18:03:45      NaN  439.790      NaN
2013-05-16 18:17:45  465.195      NaN      NaN