如何在 Pandas Dataframe 中汇总时间序列数据中的缺失值?

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

我有一个如下所示的时间序列数据集:

如图所示,通道值有三列与同一组时间戳配对。 每个通道都有一组 NaN 值。

我的objective是创建这些NaN值的总结如下:

我的方法(低效):先创建一个for循环遍历每个通道列,然后再创建一个嵌套for循环遍历通道的每一行。然后当它偶然发现 NaN 值集时,它可以以单独的行(或列表)的形式注册开始时间戳、结束时间戳和持续时间,我最终可以将它们堆叠在一起作为最终输出。

但我的逻辑似乎效率很低而且很慢,尤其是考虑到我的原始数据集有 200 个通道列和 10k 行。我敢肯定 Python.

中应该有比这更好的方法

任何人都可以帮我解决这个问题 - 在 Python 中使用 Pandas 吗?

使用:

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])])

使用DataFrame.melt重塑DataFrame,然后通过缺失值和缺失后的下一个值过滤连续的组,并通过聚合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