簡體   English   中英

只取熊貓中兩個連續值的平均值

[英]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和過濾器只有一個abc ,因為我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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM