uuid site ts visit
0 +CW99 1124 2013-06-24 2
1 +CW99 1124 2013-06-26 1
2 +CW99 1124 2013-06-27 1
3 +CW99 1124 2013-06-20 1
4 +CW99 1124 2013-06-21 1
5 +CW99 1124 2013-06-24 2
6 +CW9W 956 2013-06-21 4
7 +CW9W 956 2013-06-22 2
8 +CW9W 956 2013-06-23 3
9 +CW9W 956 2013-06-24 4
我有一个传递的数据帧。我真的不知道有多少不同的ts时期。所以我想找到ts的最小值和最大值然后将没有所有ts(每日)的行扩展为零填充访问列,同时复制其余字段
uuid site ts visit
0 +CW99 1124 2013-06-20 1
1 +CW99 1124 2013-06-21 1
2 +CW99 1124 2013-06-22 1
3 +CW99 1124 2013-06-23 0
4 +CW99 1124 2013-06-24 2
5 +CW99 1124 2013-06-25 0
6 +CW99 1124 2013-06-26 1
7 +CW99 1124 2013-06-27 1
8 +CW9W 956 2013-06-20 0
9 +CW9W 956 2013-06-21 4
10 +CW9W 956 2013-06-22 2
11 +CW9W 956 2013-06-23 3
12 +CW9W 956 2013-06-24 4
13 +CW9W 956 2013-06-25 0
14 +CW9W 956 2013-06-26 0
15 +CW9W 956 2013-06-27 0
感谢。
答案 0 :(得分:4)
这不重要。我将在下面解释原因
Prelim,请阅读原始数据框,确保ts
列的格式为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,网站进行分组)
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
没有办法)。如果你愿意,可以放下这些。