[英]Python: Pandas, how to select rows that in different ranges of date after groupby
I have a dataframe like this:我有一个像这样的 dataframe:
ID Date Value
0 A 2018-01-01 -1.452486
1 A 2018-01-02 -0.554813
2 A 2018-01-03 0.710189
3 A 2018-01-04 1.980976
4 A 2018-01-05 1.586007
... ... ... ...
1090 C 2018-12-27 0.020119
1091 C 2018-12-28 -0.720705
1092 C 2018-12-29 -0.124303
1093 C 2018-12-30 0.921005
1094 C 2018-12-31 0.073129
Each group of ID has a row that value
is 100:每组 ID 有一行
value
100:
ID Date Value
54 A 2018-02-24 100.0
554 B 2018-07-09 100.0
854 C 2018-05-05 100.0
Now I want to select a subset of the dataframe that based on its Date
whose value
is 100 and backward 2 weeks:现在我想 select dataframe 的一个子集,它基于其
value
100 和向后 2 周的Date
:
ID Date Value
41 A 2018-02-11 0.841923
42 A 2018-02-12 -1.116607
43 A 2018-02-13 0.560046
44 A 2018-02-14 -0.359288
45 A 2018-02-15 2.091080
46 A 2018-02-16 -0.827285
47 A 2018-02-17 0.061536
48 A 2018-02-18 0.536367
49 A 2018-02-19 0.379075
50 A 2018-02-20 0.442490
51 A 2018-02-21 -0.461630
52 A 2018-02-22 0.496318
53 A 2018-02-23 1.478587
54 A 2018-02-24 100.000000
541 B 2018-06-26 -0.425352
542 B 2018-06-27 0.489837
543 B 2018-06-28 2.421981
544 B 2018-06-29 2.068240
545 B 2018-06-30 0.733924
546 B 2018-07-01 -0.505563
547 B 2018-07-02 -0.199901
548 B 2018-07-03 1.116411
549 B 2018-07-04 -0.652445
550 B 2018-07-05 2.327285
551 B 2018-07-06 0.443507
552 B 2018-07-07 0.227356
553 B 2018-07-08 -0.951611
554 B 2018-07-09 100.000000
841 C 2018-04-22 -0.214560
842 C 2018-04-23 1.189581
843 C 2018-04-24 0.375965
844 C 2018-04-25 1.721489
845 C 2018-04-26 0.819428
846 C 2018-04-27 -0.777456
847 C 2018-04-28 -0.560471
848 C 2018-04-29 -0.437284
849 C 2018-04-30 -0.786168
850 C 2018-05-01 0.780642
851 C 2018-05-02 -0.634718
852 C 2018-05-03 1.541415
853 C 2018-05-04 -0.905156
854 C 2018-05-05 100.000000
I have tried groupby()
, filter()
and between_time()
but could not get the desired output.我已经尝试过
groupby()
、 filter()
和between_time()
但无法获得所需的 output。
Here is the input dateframe of above:这是上面的输入日期框:
from itertools import chain
import random
import pandas as pd
import numpy as np
df_1 = pd.DataFrame({
'ID' : list(chain.from_iterable([['A'] * 365, ['B'] * 365, ['C'] * 365])),
'Date' : pd.date_range(start = '2018-01-01', end = '2018-12-31').tolist() + pd.date_range(start = '2018-01-01', end = '2018-12-31').tolist() + pd.date_range(start = '2018-01-01', end = '2018-12-31').tolist(),
'Value' : np.random.randn(365 * 3)
})
df_1.iloc[54, 2] = 100
df_1.iloc[554, 2] = 100
df_1.iloc[854, 2] = 100
Thanks for the help!谢谢您的帮助!
Using GroupBy.apply
and then finding the row which has Value 100
and using pd.DateOffset
to get the rows between 2 weeks before:使用
GroupBy.apply
然后找到具有Value 100
的行并使用pd.DateOffset
获取两周前的行:
df_1.groupby('ID')\
.apply(lambda x: x.loc[x['Date']\
.between(x.loc[x['Value'].eq(100), 'Date'].iat[0]-pd.DateOffset(weeks=2),
x.loc[x['Value'].eq(100), 'Date'].iat[0])]).reset_index(drop=True)
Or more readable in a function:或者在 function 中更具可读性:
def get_rows(x):
date = x.loc[x['Value'].eq(100), 'Date'].iat[0]
newdata = x.loc[x['Date'].between(date-pd.DateOffset(weeks=2), date)]
return newdata
grp = df_1.groupby('ID').apply(get_rows).reset_index(drop=True)
Output Output
ID Date Value
0 A 2018-02-10 1.493770
1 A 2018-02-11 1.141011
2 A 2018-02-12 0.169845
3 A 2018-02-13 0.978423
4 A 2018-02-14 0.685567
5 A 2018-02-15 -0.268094
6 A 2018-02-16 -0.256714
7 A 2018-02-17 -1.565485
8 A 2018-02-18 2.889279
9 A 2018-02-19 0.236144
10 A 2018-02-20 0.484225
11 A 2018-02-21 -1.244975
12 A 2018-02-22 -0.476240
13 A 2018-02-23 0.744125
14 A 2018-02-24 100.000000
15 B 2018-06-25 -1.256417
16 B 2018-06-26 -0.392734
17 B 2018-06-27 -0.615133
18 B 2018-06-28 -0.410776
19 B 2018-06-29 -2.246637
20 B 2018-06-30 -0.389098
21 B 2018-07-01 0.257526
22 B 2018-07-02 -0.865095
23 B 2018-07-03 1.165467
24 B 2018-07-04 0.914455
25 B 2018-07-05 0.306181
26 B 2018-07-06 -0.903388
27 B 2018-07-07 -1.244789
28 B 2018-07-08 0.526398
29 B 2018-07-09 100.000000
30 C 2018-04-21 1.370516
31 C 2018-04-22 0.207436
32 C 2018-04-23 1.087256
33 C 2018-04-24 -1.031925
34 C 2018-04-25 -0.279739
35 C 2018-04-26 -0.627787
36 C 2018-04-27 -0.149531
37 C 2018-04-28 0.237061
38 C 2018-04-29 -0.756877
39 C 2018-04-30 -0.855831
40 C 2018-05-01 -0.864244
41 C 2018-05-02 -1.159661
42 C 2018-05-03 -1.430411
43 C 2018-05-04 0.708505
44 C 2018-05-05 100.000000
You can use groupby and apply a lamdba function that grabs the Value==100 element and backtracks 14 days.您可以使用 groupby 并应用 lamdba function 来获取 Value==100 元素并回溯 14 天。
df_1.groupby('ID').apply(lambda g: g.loc[
g.Date.gt(g.query('Value==100').Date.iloc[0] - pd.Timedelta(14, 'D'))
& g.Date.le(g.query('Value==100').Date.iloc[0])
]).reset_index(level=0, drop=True)
# returns:
ID Date Value
41 A 2018-02-11 -0.974209
42 A 2018-02-12 0.090468
43 A 2018-02-13 0.052444
44 A 2018-02-14 0.070550
45 A 2018-02-15 -0.989467
46 A 2018-02-16 0.355879
47 A 2018-02-17 -0.480722
48 A 2018-02-18 -0.631650
49 A 2018-02-19 -0.683452
50 A 2018-02-20 1.285355
51 A 2018-02-21 1.377012
52 A 2018-02-22 0.544838
53 A 2018-02-23 0.118181
54 A 2018-02-24 100.000000
541 B 2018-06-26 1.012775
542 B 2018-06-27 0.543416
543 B 2018-06-28 -0.071764
544 B 2018-06-29 -0.828533
545 B 2018-06-30 -0.082200
546 B 2018-07-01 1.260128
547 B 2018-07-02 0.936050
548 B 2018-07-03 1.861192
549 B 2018-07-04 -0.299974
550 B 2018-07-05 0.841579
551 B 2018-07-06 -0.218278
552 B 2018-07-07 -0.757397
553 B 2018-07-08 0.928673
554 B 2018-07-09 100.000000
841 C 2018-04-22 -1.148765
842 C 2018-04-23 -0.496060
843 C 2018-04-24 0.559782
844 C 2018-04-25 0.913943
845 C 2018-04-26 0.027123
846 C 2018-04-27 1.474957
847 C 2018-04-28 1.352606
848 C 2018-04-29 -1.324069
849 C 2018-04-30 0.165570
850 C 2018-05-01 0.771027
851 C 2018-05-02 -0.568807
852 C 2018-05-03 1.581479
853 C 2018-05-04 0.999872
854 C 2018-05-05 100.000000
With the following structure you get the breakpoints where the value 100 is present in your dataframe.通过以下结构,您可以获得 dataframe 中存在值 100 的断点。
for x,i in zip(df_1['Value'] == 100,df_1.index):
if x:#boolean True if Value = 100
two_weeks = (i-15)
print(df_1.iloc[two_weeks:i])
ID Date Value
39 A 2018-02-09 1.405063
40 A 2018-02-10 -0.885830
41 A 2018-02-11 -0.618240
42 A 2018-02-12 0.189675
43 A 2018-02-13 -1.128798
44 A 2018-02-14 -0.847795
45 A 2018-02-15 -0.548889
46 A 2018-02-16 -0.672275
47 A 2018-02-17 1.402386
48 A 2018-02-18 1.559774
49 A 2018-02-19 0.496039
50 A 2018-02-20 0.172402
51 A 2018-02-21 -0.260821
52 A 2018-02-22 1.099741
53 A 2018-02-23 0.917311
ID Date Value
539 B 2018-06-24 0.148511
540 B 2018-06-25 0.975276
541 B 2018-06-26 0.874365
542 B 2018-06-27 -0.143335
543 B 2018-06-28 1.011093
544 B 2018-06-29 0.180327
545 B 2018-06-30 1.629272
546 B 2018-07-01 -0.876905
547 B 2018-07-02 0.450003
548 B 2018-07-03 0.338859
549 B 2018-07-04 -1.590210
550 B 2018-07-05 -0.659832
551 B 2018-07-06 0.187246
552 B 2018-07-07 0.503597
553 B 2018-07-08 -0.378273
ID Date Value
839 C 2018-04-20 0.597722
840 C 2018-04-21 -1.407209
841 C 2018-04-22 1.339154
842 C 2018-04-23 -1.070049
843 C 2018-04-24 2.104513
844 C 2018-04-25 -0.242507
845 C 2018-04-26 -0.313100
846 C 2018-04-27 0.579189
847 C 2018-04-28 0.812848
848 C 2018-04-29 0.288989
849 C 2018-04-30 1.092859
850 C 2018-05-01 0.509114
851 C 2018-05-02 0.151621
852 C 2018-05-03 0.635293
853 C 2018-05-04 0.768101
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.