填充DataFrame,缺少数据

时间:2017-06-06 17:21:09

标签: python pandas dataframe time missing-data

描述

我读了一个包含三列的表:ID,时间和位置来创建数据帧。 ID是第一个索引,time是第二个索引。我希望时间频率为五分钟,如果相应时间没有数据,请将位置设置为最后一个位置(参见下表)。

现在的数据框

ID   time          place
001  00:00:00      1
     00:15:00      3
002  00:05:00      2

我希望得到的数据框

ID   time          place
001  00:00:00      1  
     00:05:00      1
     00:10:00      1
     00:15:00      3
#continue to fill the table until 23:55:00   

002  00:00:00      2
     00:05:00      2
#continue to fill the table until 23:55:00 

代码

def create_table(n):
  table = pd.read_table(n,sep='\x01', header=None, names=['ID','time','place'])
  table['time'] = pd.to_datetime(table['time'], format='%H:%M:%S')
  table = table.set_index('ID','time')
  return table 

我不知道如何继续制作理想的数据帧。任何人都可以给我一些提示吗?非常感谢!!

1 个答案:

答案 0 :(得分:2)

要获取上面定义的DataFrame,我们可以:

df = pd.DataFrame({'ID': ['001', '001', '002'], 'time': ['00:00:00', '00:15:00', '00:05:00'], 'place': [1, 3, 2]}).set_index(['ID', 'time'])

为了能够只使用时间并对每个ID值应用相同的操作,让我们取消堆栈'ID',这样我们就有了一个列的多索引,我们的ID位于顶层:

In [91]: df = df.unstack(0)

In [92]: df
Out[92]:
         place
ID         001  002
time
00:00:00   1.0  NaN
00:05:00   NaN  2.0
00:15:00   3.0  NaN

现在,让我们将索引(现在只是'时间')转换为DatetimeIndex:

In [93]: df.index = pd.to_datetime(df.index)

In [94]: df
Out[94]:
                    place
ID                    001  002
time
2017-06-06 00:00:00   1.0  NaN
2017-06-06 00:05:00   NaN  2.0
2017-06-06 00:15:00   3.0  NaN

这增加了今天的日期,但我们可以稍后删除。

接下来,让我们创建另一个DatetimeIndex,包含今天日期的5分钟增量:

In [95]: times = pd.date_range("00:00:00", "23:55:00", freq="5min")

In [96]: times
Out[96]:
DatetimeIndex(['2017-06-06 00:00:00', '2017-06-06 00:05:00',
               '2017-06-06 00:10:00', '2017-06-06 00:15:00',
               '2017-06-06 00:20:00', '2017-06-06 00:25:00',
               '2017-06-06 00:30:00', '2017-06-06 00:35:00',
               '2017-06-06 00:40:00', '2017-06-06 00:45:00',
               ...
               '2017-06-06 23:10:00', '2017-06-06 23:15:00',
               '2017-06-06 23:20:00', '2017-06-06 23:25:00',
               '2017-06-06 23:30:00', '2017-06-06 23:35:00',
               '2017-06-06 23:40:00', '2017-06-06 23:45:00',
               '2017-06-06 23:50:00', '2017-06-06 23:55:00'],
              dtype='datetime64[ns]', length=288, freq='5T')

让我们根据这个新的DatetimeIndex重新索引我们的df索引:

In [97]: df = df.reindex(times)

In [98]: df
Out[98]:
                    place
ID                    001  002
2017-06-06 00:00:00   1.0  NaN
2017-06-06 00:05:00   NaN  2.0
2017-06-06 00:10:00   NaN  NaN
2017-06-06 00:15:00   3.0  NaN
2017-06-06 00:20:00   NaN  NaN
...

现在我们只需要转发填充,这样每次该位置都是最后一个非NaN位置:

In [99]: df = df.ffill()

In [100]: df
Out[100]:
                    place
ID                    001  002
2017-06-06 00:00:00   1.0  NaN
2017-06-06 00:05:00   1.0  2.0
2017-06-06 00:10:00   1.0  2.0
2017-06-06 00:15:00   3.0  2.0
2017-06-06 00:20:00   3.0  2.0
2017-06-06 00:25:00   3.0  2.0
2017-06-06 00:30:00   3.0  2.0
...

从这里开始,我们需要摆脱日期:

In [101]: df.index = df.index.strftime('%H:%M:%S')

In [102]: df
Out[102]:
         place
ID         001  002
00:00:00   1.0  NaN
00:05:00   1.0  2.0
00:10:00   1.0  2.0
00:15:00   3.0  2.0
00:20:00   3.0  2.0
00:25:00   3.0  2.0
...

我们在'时间'指数上丢失了名字,所以让我们把它放回去:

df.index = df.index.set_names('time')

最后,将'ID'放回索引中:

In [103]: df.stack(1).swaplevel(0, 1)
Out[103]:
              place
ID  time
001 00:00:00    1.0
    00:05:00    1.0
002 00:05:00    2.0
001 00:10:00    1.0
002 00:10:00    2.0
001 00:15:00    3.0
...