8 u) m# C' c( K" ]% wTimedeltaIndex(['1 days', '2 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq='D') , [; Q: z u. Q- [+ BTimedeltaIndex(['0 days 12:00:00', '0 days 14:00:00', '0 days 16:00:00', 2 r! q7 r6 q: h' P '0 days 18:00:00', '0 days 20:00:00'], dtype='timedelta64[ns]', freq='2H') 9 e# v$ e; Z2 i; ?" NDatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04',9 z/ r2 Q8 k8 w% m$ g# x: o
'2020-01-05'], 4 o+ | S/ }9 d dtype='datetime64[ns]', freq='D')( T, T# r) N' X4 r9 r. D
1 & @/ [ l# \0 C9 M2$ m8 J" n0 L2 r) n$ R( O' N
3 , F4 @* b' W' M: X! [4 * R0 Q/ }- N, \2 [0 t5 # w, `& S' Z1 b4 T7 z6 / U8 H3 o0 t1 v2 \2 r) |7! p9 d6 _: Z5 W, F2 M/ g
8, X1 b- i5 D7 Q% \3 B1 }$ ~ t4 t
9 5 o9 l. v5 v4 @: e9 k106 |0 n" C0 V! g, B1 c0 V1 I8 i
11& e( [$ n# I8 Q Q( M$ ]( K
12 : H/ U {3 j- x7 F, \% |+ a13& r% C+ [2 Q0 \( b# u# S
td1 * 5 L j0 P. `; J5 UOut[77]: TimedeltaIndex(['5 days', '10 days', '15 days', '20 days', '25 days'], dtype='timedelta64[ns]', freq='5D') % h( [6 ?6 Z1 M2 Q7 K, \* m5 ^- z4 }& J
td1 * pd.Series(list(range(5))) # 逐个相乘 + M1 y# B# z5 l2 Z( Q4 E9 OOut[78]: + O; u2 F' g4 x8 K9 L% ]- A& a0 0 days : V5 R# w5 A$ B9 P* l" V8 h1 2 days( j7 z7 m: J% a. X- ]- \
2 6 days % S0 [8 u" B5 W8 W3 12 days / N8 F6 X% C7 b1 Q- l2 W4 20 days & T7 A# e) g1 `1 O; Kdtype: timedelta64[ns]/ M& s$ l8 G- [: C- B4 y
1 Q v. ?- A# V" }, c/ ?td1 - td2- l/ L b6 a( X, F1 W8 P9 ~* m
Out[79]: / @" b5 K* P4 K# G" f$ JTimedeltaIndex(['0 days 12:00:00', '1 days 10:00:00', '2 days 08:00:00',( U) x% q- p7 n5 _8 H5 z
'3 days 06:00:00', '4 days 04:00:00'],, a+ B. A+ D" b7 N4 N# S
dtype='timedelta64[ns]', freq=None)! c3 e8 d7 g R" t0 a
" C' ]9 \* h( d* f' E; m3 S& I6 mtd1 + pd.Timestamp('20200101'), Z, G% ]9 j! p4 f9 g$ t2 C
Out[80]: 7 | g4 p/ w8 r* O# G2 U8 P1 uDatetimeIndex(['2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05', 9 b, Y" ^$ ^" m/ R9 U0 D0 h+ u '2020-01-06'],dtype='datetime64[ns]', freq='D'): ?/ m3 n0 m: F6 @
5 b m$ n5 j8 a' e9 v0 r
td1 + ts # 逐个相加+ d6 \- ?( s1 H0 v9 V( F
Out[81]: 3 \7 ]0 I5 s6 p" n. s# a, I5 R% zDatetimeIndex(['2020-01-02', '2020-01-04', '2020-01-06', '2020-01-08', 3 ]9 n- J, J" e' T, i '2020-01-10'],- Y3 v% t8 U6 K; `1 F, M# W) |
dtype='datetime64[ns]', freq=None) 7 a$ C( @. w( [, k ' ^/ H! x* o% b$ T5 p/ |1 % g" W+ z7 e4 z9 `2 f" Z2 b25 k1 d8 z: h- B7 a
3# t: y; N$ K! q0 w+ S
4+ \- H6 B6 Z1 Y+ q8 t* ]7 `$ e
5 ) U; X2 H$ U" r9 Y64 {( E+ v, T1 _6 K q H5 Z) t w
7( g8 H6 r; y/ [5 X
84 c( e7 {2 N) H* v
92 l% D; ?6 E0 S! x( ~9 B- ~
106 D' Q& B5 U2 A3 v& H* D! j; J
11/ e2 c5 a- l& n
124 N4 H5 ?% X3 i: Z% L
13 3 w+ q" t v- p8 s. k' n. z, Y14' p6 ~5 q6 z4 B, C+ N
15 0 I9 D/ }$ G% x! X16! \/ B. K, C8 {& `( T, x2 u* w
17 ' y# g* x3 ?* B! U" Q18; |/ M$ l+ ?; U' ?
19 / \. q, F( m8 x; j4 d20$ q# m( C+ @/ D. |8 B/ u: m3 H
21 + G/ {# ^+ W' M {! V3 u221 C- A w! ~1 l$ g, G1 x
23. o3 C D# n7 C# l( F
24( {; M) k0 z$ d: a
25* e. B2 Q( m$ e4 l) s" `3 q) \
26' R u! Q! a" `2 K( C
271 c6 D) K N: g; x o! [. T D/ @% Q
287 n/ b% U4 B1 e, f* L0 ~0 O
10.4 日期偏置9 x3 a+ @2 Z7 m& u6 z" w
10.4.1 Offset对象 % b5 }, |( w; ~& c2 Z+ X0 c 日期偏置是一种和日历相关的特殊时间差,例如回到第一节中的两个问题:如何求2020年9月第一个周一的日期,以及如何求2020年9月7日后的第30个工作日是哪一天。& X: i+ @8 ?8 P
3 V! u+ `! w; Z2 m( K5 S; z8 [
DateOffset 类有10个属性,假设s=pd.offsets.WeekOfMonth(week=0,weekday=0),则: 1 G6 U' L0 _: M+ k! B% { b: \7 y8 R9 M- p/ f4 |6 w# W v2 zs.base:<WeekOfMonth: week=0, weekday=0>,返回 n=1 且所有其他属性一样的副本! ^- n% H A6 D/ b
s.kwds:{‘week’: 0, ‘weekday’: 0} 6 P3 l+ i* V, Os.wek/s.weekday:顾名思义, r* j% `4 l; X# |8 e
有14个方法,包括: 5 r o. d2 h& p: _+ _, U7 Y2 J8 w' N' i' Y
DateOffset.is_month_start、DateOffset.is_month_end、DateOffset.is_quarter_start、DateOffset.is_quarter_end、DateOffset.is_year_start、DateOffset.is_year_end等等。+ b- G6 H) m- g2 g
pandas.tseries.offsets.WeekOfMonth(week,weekday):描述每月的日期,例如“每月第二周的星期二”。 + S' o- O$ i9 ?5 I 9 m" }! ]7 i8 F有两个参数:$ t2 H" J& @# f. z, w+ x
week:整型,表示一个月的第几周。例如 0 是一个月的第 1 周,1 是第 2 周,以此类推。4 x7 k0 E$ @. f; i: O5 L ^ [! c
weekday:整型,取值为[0,1,…6],表示周一到周日,默认取值为0(星期一) & v7 _% P7 E* [" w1 K+ K$ wpandas.tseries.offsets.BusinessDay(n):相当于pd.offsets.BDay(n),DateOffset 子类,表示可能的 n 个工作日。 9 [' v5 D: J3 W 4 o X& s! a0 u) Q! g1 zpd.Timestamp('20200831') + pd.offsets.WeekOfMonth(week=0,weekday=0) / [# ^" h) t3 T- i. r1 ^1 z1 A* ZOut[82]: Timestamp('2020-09-07 00:00:00') ! F6 D" a# D0 { / i; Q$ J. Q, A6 hpd.Timestamp('20200907') + pd.offsets.BDay(30) + M8 G; P [9 ~: H. a* zOut[83]: Timestamp('2020-10-19 00:00:00'): H' Q( x; o6 ?& Z3 v6 k
1 - _7 V: U5 Q9 n6 I# ?4 u2 + e& E* G: F' S2 I' h3 # ^7 I& s- b1 d/ c% s' M; p4 4 G3 w7 q- x( X% W5 O+ `5 ) x: L4 m$ u2 \% y3 m! S4 Q- { 从上面的例子中可以看到,Offset对象在pd.offsets中被定义。当使用+时获取离其最近的下一个日期,当使用-时获取离其最近的上一个日期:8 o/ a/ ~& q9 d6 Y! b% \5 Y4 c
8 S6 B# j* I$ Lpd.Timestamp('20200831') - pd.offsets.WeekOfMonth(week=0,weekday=0)/ Y! D5 I" ^" C& ]# b
Out[84]: Timestamp('2020-08-03 00:00:00') ! {& J' K" I. Z: ^8 I ' k2 p2 F' ^% U$ B Mpd.Timestamp('20200907') - pd.offsets.BDay(30)$ a* J5 s% a+ @2 b
Out[85]: Timestamp('2020-07-27 00:00:00') ! U# Q' C8 O+ G9 m8 M( G) L4 [/ G- I" B7 S* H$ }
pd.Timestamp('20200907') + pd.offsets.MonthEnd() 7 r2 z) q2 r( r4 n K6 _8 SOut[86]: Timestamp('2020-09-30 00:00:00') C, x* y( p* y8 S6 B1 3 r( _: w& M5 s& J4 b2 % W M8 u, t* h4 g; ~' R4 M3/ }) k3 v+ i( M# l' t4 F
4* e/ j7 Z. `% R4 c* P
5 O7 S, a# I e1 m- {2 L, p/ H5 F# o64 Q8 C9 s+ D$ R' h
7+ d" k; z, @3 \4 `8 p
8- t3 r( G X5 p& m: r2 A
常用的日期偏置如下可以查阅这里的DateOffset 文档描述。在文档罗列的Offset中,需要介绍一个特殊的Offset对象CDay。CDay 或 CustomBusinessDay 类提供了一个参数化的 BusinessDay 类,可用于创建自定义的工作日日历,该日历说明当地假期和当地周末惯例。 ' u7 D9 ^' u( W 其中的holidays, weekmask参数能够分别对自定义的日期和星期进行过滤,前者传入了需要过滤的日期列表,后者传入的是三个字母的星期缩写构成的星期字符串,其作用是只保留字符串中出现的星期:! \ g8 K7 [( X. R
# ^6 |1 Y5 Z4 b8 A6 P; D! c1 zmy_series.diff(1).head() : A/ _; v. ]& O9 \0 LOut[116]: 1 X- x( r7 A& H1 l
0 NaT" n' p+ L; j8 c' n5 s/ K
1 1 days 4 |8 W) N8 P8 c: P0 K% J T2 1 days & R1 r3 w* I/ L% I3 3 days! P/ ~9 B: j6 H* }- W% k! C1 b5 w
4 1 days 3 p1 j6 V5 F/ ^dtype: timedelta64[ns]( e; O: `" l+ @* i& |; @
$ h( d2 f5 j5 L
1 2 t' W% O3 m% y& T2 . D* d7 e" z$ p3 , r5 d6 F& U" M% c4 6 x4 Q! _2 H; d; F6 l& N5 6 m2 y5 Y- C" {5 y: e' x6 * K2 P. c, }. b5 b; v7 6 D( Y6 [: \; I& v# t3 c8 3 K v( B. Z, r, S. h5 C& H, W/ z1 w9 2 ?. A8 B# i1 y! `: R6 ~% E10 % U/ {7 U, `8 E# m+ [* R u11 9 Y O# x4 Y5 e" j0 x. j/ h7 L12 % x$ U0 x0 a) W% A( n8 @13 . d, j* F7 `) t, X( l14 1 f( F1 W4 m$ A' q* H; I; Y15' c2 w5 i2 N) Q- b4 J2 @( D( N
161 u% R8 B, Y: l" d7 i) v
17 ! h0 T( ]3 B( L# u% S, N18 + ]# i' q5 v% q* h10.5.2 重采样- l% s" d& |0 O# p% t
DataFrame.resample(rule, axis=0, closed=None, label=None, convention=‘start’, kind=None, loffset=None, base=None, on=None, level=None, origin=‘start_day’, offset=None)! L% \- v4 U' Z
常用参数有: ) H. [4 ^( y3 g2 |) k/ d) W" q6 ]3 i: d0 r M9 `* |
rule:DateOffset, Timedelta or str类型。表示偏移量字符串或对象 * i4 C0 `. k' p" r4 c) saxis:{0 or ‘index’, 1 or ‘columns’}, default 0。使用哪个轴进行上采样或下采样 % f( L$ V- j7 u0 lclosed:{‘right’, ‘left’},默认None。表示bin 区间的哪一侧是闭合的。所有offsets的默认值为“left”,但“M”、“A”、“Q”、“BM”、“BA”、“BQ”和“W”均默认为“right”。 9 U- {6 [% b$ `; q3 ylabel:{‘right’, ‘left’}, 默认 None。hich bin edge label to label bucket with,所有offsets的默认值为“left”,但“M”、“A”、“Q”、“BM”、“BA”、“BQ”和“W”均默认为“right”。 5 }, h+ w' i1 O9 f5 v, M% }convention{:‘start’, ‘end’, ‘s’, ‘e’}, default ‘start’。仅针对 PeriodIndex,控制是使用rule的开始还是结尾。 6 d: b, g+ N+ c s0 Xon:字符串类型,可选。对于 DataFrame,使用列而不是索引进行重采样。列必须类似于日期时间。 5 C2 r. O( d, a+ V- z" b- |1 plevel:str 或 int,可选表示多重索引MultiIndex的级别,这个级别的索引必须类似于日期时间。 , V' D& G, U: O" p$ e$ Xorigin参数有5种取值: ' I9 z+ m- _4 y# O‘epoch’:从 1970-01-01开始算起) z4 k/ p/ q2 e" _& ~/ p
‘start’:原点是时间序列的第一个值 , K, l+ o, V& l6 L& d2 ]/ T- B2 e5 e/ H‘start_day’:默认值,表示原点是时间序列第一天的午夜。 6 w& n F& I7 N4 a& o'end':原点是时间序列的最后一个值(1.3.0版本才有)* X, D$ k, f! U7 s. L: T/ X5 k
‘end_day’:原点是序列最后一天的午夜(1.3.0版本才有) 4 }9 o0 ~* e+ K% b; Hoffset:Timedelta 或 str,默认为 None,表示对时间原点的偏移量,很有用。 3 V7 X) ?7 {+ B closed和计算有关,label和显示有关,closed才有开闭。$ `+ \( J) ^% z" x: g8 g
label指这个区间值算出来了,索引放区间的左端点还是右端点,closed是指算的时候左端点或右端点是不是包含。% n, W- ]2 E2 _5 \- n
, A: d0 B" R# E% X
重采样对象resample和第四章中分组对象groupby的用法类似,resample是针对时间序列的分组计算而设计的分组对象。例如,对上面的序列计算每10天的均值:/ d' i u8 b* D+ K" q7 g" r2 l
s.resample('10D').mean().head() * s6 s+ g( C' |8 S% O; T8 FOut[117]: " J9 }& x8 K a! O2020-01-01 -2.000000. V% O/ L4 w, K i6 F
2020-01-11 -3.166667 $ N/ {2 n# u; g, F9 K2020-01-21 -3.625000) d1 N+ Y, `7 n, P3 q
2020-01-31 -4.000000 " p6 n* [. [7 D( v( H5 _2020-02-10 -0.375000% [$ ^3 u" b p; S E- R% F
Freq: 10D, dtype: float64 3 l1 O- c3 I8 {1 8 c5 @% s3 ]! c' R4 m! i2( t' o6 U c+ b( j$ d
3 6 O. p$ u m& E! k; \* W8 D1 l5 l( U4 0 z* F( [. y5 B# l. o- |4 @9 a: x51 e2 x" M7 Z- w5 {) Q# j' B8 Y
6 3 D5 E6 n9 m4 A1 Z3 b3 w* V78 N- M% \$ Q& v/ ^' H4 a S5 U+ Q
8 F8 }% g/ N& e可以通过apply方法自定义处理函数: 4 d% D* l' n; {4 ] o. F6 Ms.resample('10D').apply(lambda x:x.max()-x.min()).head() # 极差- J) d. W0 l5 F' D/ c/ K
: `! o' A7 ~5 T; l- n( ~, \Out[118]: ) \8 a& k" U" j2 F R2020-01-01 3( {. {4 H" k4 _) c% {9 ~
2020-01-11 4 : h1 s6 M2 T7 g8 \. a7 X2020-01-21 4 * s0 A. h7 j5 M2 S. P! b( d2020-01-31 2 * d7 _3 Q: w, c: J" S$ Q2020-02-10 4 ! n" Z& D* _5 T5 s- Y% c9 s9 NFreq: 10D, dtype: int32! Y& p# i; M+ A2 D& M7 j/ ?
1 1 i$ T R: V, b! `2$ _# e- O" N; ~
3 * a) v6 H; o7 R4 B+ o3 `47 ]( K5 \7 p9 c, ^. M3 A+ m
5/ G& A, J3 o# X a' e! p+ I. i
6 - p% N9 E9 b' `7 % P! ]; n0 x( |1 b" `* A. ?8 : b- M7 ~/ ?6 p) M+ y) j9 & E `' {) K' ?1 p0 d- ~9 q 在resample中要特别注意组边界值的处理情况,默认情况下起始值的计算方法是从最小值时间戳对应日期的午夜00:00:00开始增加freq,直到不超过该最小时间戳的最大时间戳,由此对应的时间戳为起始值,然后每次累加freq参数作为分割结点进行分组,区间情况为左闭右开。下面构造一个不均匀的例子:" c" p' a2 ]: d: U! h
( W( S1 J3 K7 v% d% U
idx = pd.date_range('20200101 8:26:35', '20200101 9:31:58', freq='77s'): c) y* u2 T% o
data = np.random.randint(-1,2,len(idx)).cumsum()& W( C# n" j* E; P+ n2 N+ e1 o4 x
s = pd.Series(data,index=idx)# Q( i4 x9 F* M; [
s.head(), i) j$ u7 M7 [3 ]7 y1 u
- M" S. {2 f0 R! A, uOut[122]: 3 `9 \0 _7 h# s ^( M. S2020-01-01 08:26:35 -1, K) H. R& q+ T
2020-01-01 08:27:52 -10 U3 G8 C! Y, r4 G
2020-01-01 08:29:09 -2 . _2 e! B/ A" v2020-01-01 08:30:26 -3; W& [, b/ [7 }% ?
2020-01-01 08:31:43 -4$ l3 E" e' {3 Z0 k3 n
Freq: 77S, dtype: int32 ) d" g! k% \, t5 R& \; t0 i1 9 X" v9 ~1 l6 G2* o- H" E- G* Z
3 8 V4 J% x# c7 N6 G, x4/ }- n0 w4 G2 Q9 X
5 1 ]0 a8 U |! E* q2 W# f# g6 N$ P62 u/ H8 z3 y& ]4 ]
7" u6 V: T! A/ W/ ?) ^1 Q. P
87 N) d K: t3 N+ f' x
9 % w s1 B) P" k c G( ^104 @4 i4 C1 O6 X) G7 ?
11, t- F/ j# f' N8 x
12 7 W/ Q+ N. U- u; u& Y! @ 下面对应的第一个组起始值为08:24:00,其是从当天0点增加72个freq=7 min得到的,如果再增加一个freq则超出了序列的最小时间戳08:26:35: 4 k# ]1 Y/ t( }: @- x6 m, }* G; M- M' x9 R2 e, ~1 C
s.resample('7min').mean().head()8 }: y% U' h- e& Y9 h
Out[123]: ( z* `& n @! ]$ l! f0 p7 m6 g* }2020-01-01 08:24:00 -1.750000 # 起始值,终点值包含最后一个值 5 M) d& [7 `# X0 F2020-01-01 08:31:00 -2.600000! d/ e5 u& p0 i% L( O8 p `
2020-01-01 08:38:00 -2.166667 ) C: u1 t! H8 C/ a i; T, r2020-01-01 08:45:00 0.200000 ' ^2 U/ y& m* g$ u( z5 }2020-01-01 08:52:00 2.833333 ; Z) }4 M/ }- Y/ h# ]4 Z. QFreq: 7T, dtype: float64 9 W4 Z/ p, \5 z% s5 ?' c" A1 . W4 P( X/ R1 {" Y8 l2 9 d) |% C) h" Z5 x4 ]: o. ^ O3# Z/ r# L$ B2 L0 p+ @, n: E
4 . G. J: d8 F; L1 x5' l9 \* t# R2 w9 A
63 ~- t- D% o7 I. c3 X
7) t j0 P3 I$ @' s
8) t3 c$ U, f( U3 w3 S( ^" f4 b4 Z/ r+ X' O2 |
有时候,用户希望从序列的最小时间戳开始依次增加freq进行分组,此时可以指定origin参数为start: / ~2 `$ E( c* Y2 c) o . V; w1 s z T! ~6 O6 ~) Os.resample('7min', origin='start').mean().head()4 Z% B$ c' Y8 c1 }2 k$ v/ j: U
Out[124]: : t: a! M7 x# I$ H( ?' A) c
2020-01-01 08:26:35 -2.333333 2 w* t! p. m. o3 O+ L3 h+ z+ g2020-01-01 08:33:35 -2.400000, @8 U. g+ W0 u( Q
2020-01-01 08:40:35 -1.333333 8 Z$ h4 V3 }. r V. [8 `2020-01-01 08:47:35 1.200000 # C0 m4 P" y; ~% l6 X3 r% l2020-01-01 08:54:35 3.166667: j( f7 J) ^% X( M! _9 w
Freq: 7T, dtype: float64 ; J- _8 S1 N. Y$ g' y% T1 5 c3 E- l, _! W: s2/ h! H3 @0 m+ q6 y
3, @. }! V* J/ ]7 ~# c2 w) G7 }$ m5 m
4; L# ~$ ^1 c0 p; d
5 . y( k- @& k8 X9 T7 O7 r0 C6 5 K. y, k1 j- i73 T1 T- a8 ~5 ~6 K/ [6 n H6 M; l
8% @0 o7 v" |4 ]6 i4 k
在返回值中,要注意索引一般是取组的第一个时间戳,但M, A, Q, BM, BA, BQ, W这七个是取对应区间的最后一个时间戳。如果想要得到正常索引,用’MS’就行。) z% |# u' n: L
8 d% b) M* t' k' Ps = pd.Series(np.random.randint(2,size=366), 2 m( E% H# e8 m' M! A index=pd.date_range('2020-01-01',) O T. A j( O2 L0 L; }% h' ]/ J. O
'2020-12-31'))- D# J, ? P% ^! Z5 K7 p
, j: E* ?/ O( }& L% Q7 B1 E0 q4 |6 y, g
s.resample('M').mean().head()3 v) n) j- ^( N+ Q8 X* c+ ~
Out[126]: 9 b" ^8 z: b" c* i2020-01-31 0.451613* R3 x7 G6 U; o% ]6 l: J. b
2020-02-29 0.4482764 K# B, k4 x; T9 F+ g
2020-03-31 0.5161295 Z! t' j3 X6 W2 C
2020-04-30 0.566667 . \4 d$ G7 ?: A( u2020-05-31 0.451613: ?5 T, b% s- l& B8 |, l
Freq: M, dtype: float64 * l% {3 v9 e) f3 G1 h 6 P/ y, l3 r" js.resample('MS').mean().head() # 结果一样,但索引是跟正常一样 $ X! i; r: \2 h U6 DOut[127]: + v. D( T6 Q+ }$ }: \
2020-01-01 0.451613 , K7 l7 a. a5 P( P) V2 M2020-02-01 0.448276) c) i3 ^) J' O" u; p
2020-03-01 0.516129* o- W% }/ a" p+ a- X% @
2020-04-01 0.566667 ' p' a: r' H8 ~/ G2020-05-01 0.4516133 ^2 r4 [. r0 Q2 z) x9 q% S: ?
Freq: MS, dtype: float64 5 y8 ?; S' b& w, l1 {1 i1 [ m0 w 2 G2 p- Y S& |1 - P/ u- n1 \' U% G1 N6 w$ p2 8 S+ [- [2 e6 D3 K. e6 V6 Z& U3' N6 s- H8 K8 ?5 x* @
4 l9 M9 p5 Y# p3 T5 ! u/ t8 l. X3 q5 x* S/ B! `9 i6 5 U1 ~+ N$ g: ]- N7: O8 N8 A5 V, H; h, v& h7 B& l* b
8: b. n. U9 Y- m7 b' O2 c1 f
9 ' }" R7 a" Z5 d/ w( V. P+ l10 ) P8 x8 S; Y" W. _9 |4 d110 i5 G4 S# a; j
125 @- b( R% X- E
13 2 J$ p+ X. J2 d) b5 |' o14! c5 P! M) r& p/ g% v/ e5 ~/ K- L
156 e5 J6 n6 S' V& \
16; U" j* E' T' {' Y3 U( [
176 n/ Y% R- C$ f( |2 \# ^# ]" v
18 2 V+ z) ]: x* t198 e& u4 t5 Y. j
20( H1 s) w6 d: j1 X& C; J
21 , D; |- V% b/ G& L7 f229 q6 f! U3 s2 H0 z7 c; V
对于 DataFrame 对象,关键字 on 可用于指定列而不是索引以进行重采样: ) P! f; o2 }8 d, I* @d = {'price': [10, 11, 9, 13, 14, 18, 17, 19],- [4 C: n7 S. l# | w$ d
'volume': [50, 60, 40, 100, 50, 100, 40, 50]} - d% L: @8 D8 f& K0 Jdf = pd.DataFrame(d); `7 i8 s+ E" ]5 L/ c
df['week_starting'] = pd.date_range('01/01/2018',1 x2 c: |2 t- h4 g; F
periods=8," F, t. z( H6 Y' J6 P
freq='W')$ R9 f6 \6 h6 _# V6 L
df1 @# u0 D4 y' U9 x
price volume week_starting 7 d E# H. c5 U: Z0 10 50 2018-01-07 v+ P) ?6 R$ R5 ?: d* }" q
1 11 60 2018-01-144 Q# T! z6 D" {$ k6 Y L# I1 ~
2 9 40 2018-01-21 F/ n* ?/ y9 S1 {& k3 13 100 2018-01-28 - [1 S" r5 }9 W/ W B$ b4 14 50 2018-02-04 ! t6 B) |/ A' E' J! s' I5 18 100 2018-02-11 3 B# a) ]5 \' J6 17 40 2018-02-18 6 A r+ U9 l% `) @: T7 19 50 2018-02-25+ R" w, `2 W& @) a, I$ O
df.resample('M', on='week_starting').mean()8 N! h0 g( k( D0 r7 h9 U, K
price volume . x) ? U! ^- R2 X( uweek_starting* v. G* r0 f' t B8 ^1 j
2018-01-31 10.75 62.5 2 Y* |3 @/ ^8 \5 M9 @4 D2018-02-28 17.00 60.0( u& K- i# T. d7 L6 J0 q4 L! a
$ N' u1 M3 Z7 Z& ~) ^" b( v& T1! ?- o& T( [5 ?4 z! s. L
2' w Z9 L. M1 h2 \7 Z$ ~- ?
3 " i3 N+ ^% K8 Y6 s4 : q. v z, |' z- n; V2 n/ U5 T5 8 x3 H& C% X, P2 `# _9 Z% i1 k3 {6 ; {! |) [- [/ v1 `72 G' ]7 E. p; W
89 {" {# k n/ C
9 ! g: Q7 c- P/ c, j1 x10 ; u3 G2 W3 q0 S0 Y, P11 } _% _- s D; d5 p
127 N* c' I# u8 F8 O
132 c0 U. R K. P: ~) Q1 `
14 ' K7 G/ T/ h0 a9 ^9 K+ G W155 I7 I1 j5 Q3 x
16: [2 \6 w* `+ c
17 + v9 e0 o* i' u' Q' t% v18) h5 P- f0 ~) u! z
19 ) W) P& V/ d! e8 p20 ! V9 d8 C" D" k' O21 ( L8 V6 a% p' o6 E; y( G9 @# G对于具有 MultiIndex 的 DataFrame,关键字 level 可用于指定需要在哪个级别进行重采样。 m1 g( e" R' ~# ^+ F; S! odays = pd.date_range('1/1/2000', periods=4, freq='D')4 ^. v' [0 i/ C9 ` z
d2 = {'price': [10, 11, 9, 13, 14, 18, 17, 19], 0 C. B/ q, f) b9 H 'volume': [50, 60, 40, 100, 50, 100, 40, 50]}- ^/ e$ H: e; U. W. k0 A
df2 = pd.DataFrame( i- z: w8 P' z d2, 8 S5 O' {/ G7 O! I5 a$ J index=pd.MultiIndex.from_product(; o) o k7 E$ Z9 z- W
[days, ['morning', 'afternoon']] ' I# {7 ^ \/ \) ` ) ( E# F. l8 I& e7 r' z) ' o2 J- I4 a" Xdf2 ) B& B5 i( [7 a' N6 }5 T8 n3 ~ price volume ) n, E$ y. n! ~2000-01-01 morning 10 50 % \) Z# q9 K! D" N afternoon 11 60' M4 b7 ?4 E6 w3 g
2000-01-02 morning 9 40& V/ E& w2 d ] V) c5 x9 k* o
afternoon 13 100: U! K7 _: z7 X* C, u3 B3 D
2000-01-03 morning 14 50 " O# q+ ?. \" b% u& O& W, t afternoon 18 100 ' o' v9 D/ k; j! {( A2000-01-04 morning 17 40 # u- [5 A& ]6 z afternoon 19 50: R2 ?" ~' p1 e8 n5 Y
df2.resample('D', level=0).sum() ) g6 y4 ?* z# i0 ?0 q+ g+ O price volume # K9 n& E0 T7 Q7 H: H: l# D2000-01-01 21 110# U- C; U( v7 M3 y7 q& _% f
2000-01-02 22 140 ( W% b D6 c/ u2 F# T8 S# y2000-01-03 32 150 * v/ h/ F" {4 ? p2000-01-04 36 904 R3 N8 R& K9 R$ e# [; Y% d: U: v; s* G