我有一个不均匀的分布式数据框,例如
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
。
答案 0 :(得分:2)
您可以先convert datetimeindex
到Unix time
,然后从index
创建新列,获取每列的mean
。上一次dropna
并按时间to_datetime
将Unix时间转换为日期时间:
print df
a b c
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
#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
index a b c
0 1368725610 485.75 NaN NaN
1 1368725640 479.16 NaN NaN
2 1368725730 NaN 429.90 NaN
3 1368725760 NaN 433.39 NaN
4 1368725850 NaN NaN 415.94
5 1368725880 NaN NaN 401.59
6 1368726570 432.23 NaN NaN
7 1368726660 NaN 424.08 NaN
8 1368726750 NaN NaN 411.67
9 1368727290 471.01 NaN NaN
10 1368727320 474.11 NaN NaN
11 1368727410 NaN 440.76 NaN
12 1368727440 NaN 438.82 NaN
13 1368728250 469.46 NaN NaN
14 1368728280 460.93 NaN NaN
df = pd.concat([df.groupby(df.a.isnull().diff().cumsum().fillna(0)).mean().set_index('index')[['a']],
df.groupby(df.b.isnull().diff().cumsum().fillna(0)).mean().set_index('index')[['b']],
df.groupby(df.c.isnull().diff().cumsum().fillna(0)).mean().set_index('index')[['c']]], axis=1)
#drop rows with all NaN, remove index name (new in 0.18)
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
说明:
首先,您需要从值创建组,其中列包含数字。您需要值0
的{{3}},因为有时函数fillna
之后的第一个值会返回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
然后您可以diff
通过此群组汇总groupby
。因为您丢失了index
,我创建了新的列index
,这也是汇总的。然后我index
从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
,因为我mean
所有聚合的数据帧都是这个新的索引。
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
如果您需要更多自动方法,请使用:
Visit <a href="http://google.com/">Google</a>, then <a href="http://bing.com">Bing</a>