簡體   English   中英

如何匯總一個Pandas Dataframe中時間序列數據的缺失值?

[英]How to summarize missing values in time series data in a Pandas Dataframe?

我有一個如下所示的時間序列數據集:

在此處輸入圖像描述

如圖所示,通道值有三列與同一組時間戳配對。 每個通道都有一組 NaN 值。

我的目標是創建這些 NaN 值的摘要,如下所示: 在此處輸入圖像描述

我的方法(效率低下):首先在每個通道列中創建一個到 go 的 for 循環,然后在通道的每一行中創建另一個嵌套的 for 循環到 go。 然后當它偶然發現 NaN 值集時,它可以以單獨行(或列表)的形式注冊開始時間戳、結束時間戳和持續時間,我最終可以將它們堆疊在一起作為最終的 output。

但是我的邏輯似乎效率很低而且很慢,尤其是考慮到我的原始數據集有 200 個通道列和 10k 行。 我確信在 Python 中應該有比這更好的方法。

誰能幫我解決這個問題——在 Python 中使用 Pandas?

使用DataFrame.melt重塑 DataFrame,然后通過 misisng 值和缺失后的下一個值過濾連續組,並通過聚合minmax創建新的DataFrame

df['date_time'] = pd.to_datetime(df['date_time'])

df1 = df.melt('date_time', var_name='Channel No.')
m = df1['value'].shift(fill_value=False).notna() #
mask = df1['value'].isna() | ~m


df1 = (df1.groupby([m.cumsum()[mask], 'Channel No.'])
          .agg(Starting_Timestamp = ('date_time','min'),
               Ending_Timestamp = ('date_time','max'))
          .assign(Duration = lambda x: x['Ending_Timestamp'].sub(x['Starting_Timestamp']))
          .droplevel(0)
          .reset_index()
        )

print (df1)
  Channel No.  Starting_Timestamp    Ending_Timestamp        Duration
0   Channel_1 2019-09-19 10:59:00 2019-09-19 14:44:00 0 days 03:45:00
1   Channel_1 2019-09-19 22:14:00 2019-09-19 23:29:00 0 days 01:15:00
2   Channel_2 2019-09-19 13:59:00 2019-09-19 19:44:00 0 days 05:45:00
3   Channel_3 2019-09-19 10:59:00 2019-09-19 12:44:00 0 days 01:45:00
4   Channel_3 2019-09-19 15:14:00 2019-09-19 16:44:00 0 days 01:30:00

利用:

inds = df[df['g'].isna()].index.to_list()
gs = []
s = 0
for i, x in enumerate(inds):
    if i<len(inds)-1:
        if x+1!=inds[i+1]:
            gs.append(inds[s:i+1])
            s = i+1
    else:
        gs.append(inds[s:i+1])
        
ses = []
for g in gs:
    ses.append([df.iloc[g[0]]['date'], df.iloc[g[-1]+1]['date']])

res = pd.DataFrame(ses, columns = ['st', 'et'])
res['d'] = res['et']-res['st']

和一個更有效的解決方案:

import pandas as pd
import numpy as np

df = pd.DataFrame({'date':pd.date_range('2021-01-01', '2021-12-01', 12), 'g':range(12)})
df['g'].loc[0:3]=np.nan
df['g'].loc[5:7]=np.nan

inds = df[df['g'].isna().astype(int).diff()==-1].index+1
pd.DataFrame([(x.iloc[0]['date'], x.iloc[-1]['date']) for x in np.array_split(df, inds) if np.isnan(x['g'].iloc[0])])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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