これは自明ではありません。その理由を以下で説明します
暫定的に、元のデータ フレームを読み取り、ts
列が dtype であることを確認します。datetime64[ns]
# you may need to do this to get the correct dtype
df['ts'] = df['ts'].to_datetime(df['ts'])
In [107]: df
Out[107]:
uuid site ts visit
0 +CW99 1124 2013-06-24 00:00:00 2
1 +CW99 1124 2013-06-26 00:00:00 1
2 +CW99 1124 2013-06-27 00:00:00 1
3 +CW99 1124 2013-06-20 00:00:00 1
4 +CW99 1124 2013-06-21 00:00:00 1
5 +CW99 1124 2013-06-24 00:00:00 2
6 +CW9W 956 2013-06-21 00:00:00 4
7 +CW9W 956 2013-06-22 00:00:00 2
8 +CW9W 956 2013-06-23 00:00:00 3
9 +CW9W 956 2013-06-24 00:00:00 4
In [106]: df.dtypes
Out[106]:
uuid object
site int64
ts datetime64[ns]
visit int64
dtype: object
最小と最大の間のマスター時間を作成します
In [110]: all_ts = pd.date_range(df['ts'].min(),df['ts'].max())
In [111]: all_ts
Out[111]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-06-20 00:00:00, ..., 2013-06-27 00:00:00]
Length: 8, Freq: D, Timezone: None
このような関数を定義します
In [103]: def f(x):
# we want all of the ``ts`` column that are not in the master time series
.....: adf = DataFrame(dict(ts = all_ts-Index(x['ts'])),columns=df.columns)
# they should have visit of 0
.....: adf['visit'] = 0
# first add them to the frame (x), ignoring the index
# sort by the ts column
# then fillforward missing values
.....: return x.append(adf,ignore_index=True).sort_index(by='ts').ffill()
.....:
関数を適用します (必要に応じて、uuid、site でグループ化することもできます)
In [116]: df.groupby('uuid').apply(f)
Out[116]:
uuid site ts visit
uuid
+CW99 3 +CW99 1124 2013-06-20 00:00:00 1
4 +CW99 1124 2013-06-21 00:00:00 1
0 +CW99 1124 2013-06-24 00:00:00 2
5 +CW99 1124 2013-06-24 00:00:00 2
6 +CW99 1124 2013-06-25 00:00:00 0
1 +CW99 1124 2013-06-26 00:00:00 1
2 +CW99 1124 2013-06-27 00:00:00 1
+CW9W 0 +CW9W 956 2013-06-21 00:00:00 4
1 +CW9W 956 2013-06-22 00:00:00 2
2 +CW9W 956 2013-06-23 00:00:00 3
3 +CW9W 956 2013-06-24 00:00:00 4
4 +CW9W 956 2013-06-25 00:00:00 0
注:投稿されたフレームに重複があります。それが意図的かどうかはわかりませんが、私はそれを保存しました。ts
(列に) 重複がない場合、これはやや簡単な問題です。
これが重複しない方法です
In [207]: def f(x):
.....: x = x.set_index('ts').reindex(all_ts).reset_index()
.....: x['visit'] = x['visit'].fillna(0)
.....: return x.ffill()
.....:
In [208]: df_no_dups.groupby('uuid').apply(f)
Out[208]:
index uuid site visit
uuid
+CW99 0 2013-06-20 00:00:00 +CW99 1124 1
1 2013-06-21 00:00:00 +CW99 1124 1
2 2013-06-22 00:00:00 +CW99 1124 0
3 2013-06-23 00:00:00 +CW99 1124 0
4 2013-06-24 00:00:00 +CW99 1124 2
5 2013-06-25 00:00:00 +CW99 1124 0
6 2013-06-26 00:00:00 +CW99 1124 1
7 2013-06-27 00:00:00 +CW99 1124 1
+CW9W 0 2013-06-20 00:00:00 NaN NaN 0
1 2013-06-21 00:00:00 +CW9W 956 4
2 2013-06-22 00:00:00 +CW9W 956 2
3 2013-06-23 00:00:00 +CW9W 956 3
4 2013-06-24 00:00:00 +CW9W 956 4
5 2013-06-25 00:00:00 +CW9W 956 0
6 2013-06-26 00:00:00 +CW9W 956 0
7 2013-06-27 00:00:00 +CW9W 956 0
これにより、すべての要素が強制的にそこに配置されます (最初の要素にはNaN
方法がないことに注意してくださいffill
)。必要に応じて、これらをドロップできます。