对 Pandas 中的组进行优雅的重新采样

Mic*_*ner 6 python group-by pandas

对于一个给定的 Pandas 数据框full_df,它看起来像

  index   id   timestamp    data  
 ------- ---- ------------ ------ 
      1    1   2017-01-01   10.0  
      2    1   2017-02-01   11.0  
      3    1   2017-04-01   13.0  
      4    2   2017-02-01    1.0  
      5    2   2017-03-01    2.0  
      6    2   2017-05-01    9.0  
Run Code Online (Sandbox Code Playgroud)

开始和结束日期(以及开始和结束之间的时间差)是不同的。

但我需要一个 id 明智的重采样版本(添加的行标记为*

  index   id   timestamp    data       
 ------- ---- ------------ ------ ---- 
      1    1   2017-01-01   10.0       
      2    1   2017-02-01   11.0       
      3    1   2017-03-01    NaN   *   
      4    1   2017-04-01   13.0       
      5    2   2017-02-01    1.0       
      6    2   2017-03-01    2.0       
      7    2   2017-04-01    NaN   *   
      8    2   2017-05-01    9.0  
Run Code Online (Sandbox Code Playgroud)

因为数据集非常大,我想知道是否有比这更有效的方法

  1. full_df.groupby('id')
  2. 为每组做 df

    df.index = pd.DatetimeIndex(df['timestamp'])
    all_days = pd.date_range(df.index.min(), df.index.max(), freq='MS')
    df = df.reindex(all_days)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用新索引再次组合所有组

这很耗时,而且不是很优雅。有任何想法吗?

Zer*_*ero 6

使用resample

In [1175]: (df.set_index('timestamp').groupby('id').resample('MS').asfreq()
              .drop(['id', 'index'], 1).reset_index())
Out[1175]:
   id  timestamp  data
0   1 2017-01-01  10.0
1   1 2017-02-01  11.0
2   1 2017-03-01   NaN
3   1 2017-04-01  13.0
4   2 2017-02-01   1.0
5   2 2017-03-01   2.0
6   2 2017-04-01   NaN
7   2 2017-05-01   9.0
Run Code Online (Sandbox Code Playgroud)

细节

In [1176]: df
Out[1176]:
   index  id  timestamp  data
0      1   1 2017-01-01  10.0
1      2   1 2017-02-01  11.0
2      3   1 2017-04-01  13.0
3      4   2 2017-02-01   1.0
4      5   2 2017-03-01   2.0
5      6   2 2017-05-01   9.0

In [1177]: df.dtypes
Out[1177]:
index                 int64
id                    int64
timestamp    datetime64[ns]
data                float64
dtype: object
Run Code Online (Sandbox Code Playgroud)