[英]Take the average only of two consecutive values in 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: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
我可以分別對待每一列。 因此,對於每一列,我可以有一個、兩個、三個甚至 4 個由nan
包圍的連續值。 我想要做的是一次只取兩個連續的行,並用它們的平均值代替它們的值,用它們的平均值代替它們的索引。 因此,我將僅用值和索引的平均值替換任何連續兩行的值。 所以上面的例子會變成
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
。 最后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
fillna
,因為有時函數diff
返回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
然后,你可以groupby
這個群體和總mean
。 因為你丟失了index
,我創建了新的列index
,它也是聚合的。 然后,我set_index
從列index
和過濾器只有一個a
, b
或c
,因為我concat
這一新指標均聚集dataframes。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.