Select个ID,增量为7天
Select IDs with an increment of 7 days
我是 python 和 pandas 的新手,正在研究 pandas 数据框,这是一个 3 个月的数据,看起来像:
Date ID product
Jul-1 1 A
Jul-1 2 B
Jul-1 3 D
Jul-4 2 F
Jul-5 1 G
Jul-9 1 K
Jul-9 2 L
Jul-9 3 X
Jul-11 1 N
Jul-13 3 M
Jul-17 1 Z
Jul-17 2 O
Jul-17 3 T
我想做的是 select ID 仅在 7 天的增量,这样它就不会 select 任何 ID 如果它在接下来的 7 天内存在最后一次被采摘的日期。生成的数据框如下所示
Date ID product
Jul-1 1 A
Jul-1 2 B
Jul-1 3 D
Jul-9 1 K
Jul-9 2 L
Jul-9 3 X
Jul-17 1 Z
Jul-17 2 O
Jul-17 3 T
从早上开始就一直在尝试,非常感谢任何帮助
提前致谢!!
这样做:
dat = pd.DataFrame([{'Date': '01/02/2016', 'ID': 1, 'product':'A'},
{'Date': '01/02/2016', 'ID': 2, 'product':'B'},
{'Date': '01/04/2016', 'ID': 4, 'product':'C'},
{'Date': '01/05/2016', 'ID': 5, 'product':'D'},
{'Date': '01/06/2016', 'ID': 6, 'product':'a'},
{'Date': '01/07/2016', 'ID': 7, 'product':'b'},
{'Date': '01/09/2016', 'ID': 8, 'product':'d'},
{'Date': '01/09/2016', 'ID': 9, 'product':'A'},
{'Date': '01/16/2016', 'ID': 10, 'product':'B'},
{'Date': '01/18/2016', 'ID': 11, 'product':'C'},
{'Date': '01/18/2016', 'ID': 12, 'product':'K'},
{'Date': '01/21/2016', 'ID': 13, 'product':'J'},
{'Date': '01/25/2016', 'ID': 14, 'product':'I'},
{'Date': '01/25/2016', 'ID': 15, 'product':'H'},
{'Date': '01/25/2016', 'ID': 16, 'product':'G'},
{'Date': '01/30/2016', 'ID': 17, 'product':'F'}]) # Replace with your data
filtered_data = pd.DataFrame(columns=['Date', 'ID', 'product'])
dat.Date = pd.to_datetime(dat.Date, format="%m/%d/%Y") # Change the format as per your data
filtered_data.loc[len(filtered_data)] = dat.iloc[0]
def trans(row):
if (row.Date - filtered_data.tail(1).iloc[0].Date).days >= 7 or (row.Date - filtered_data.tail(1).iloc[0].Date).days == 0:
filtered_data.loc[len(filtered_data)] = row
dat.apply(trans, axis=1)
print filtered_data
结果:
Date ID product
0 2016-01-02 1 A
1 2016-01-02 1 A
2 2016-01-02 2 B
3 2016-01-09 8 d
4 2016-01-09 9 A
5 2016-01-16 10 B
6 2016-01-25 14 I
7 2016-01-25 15 H
8 2016-01-25 16 G
使用来自@suicidoteddy 的数据,稍作修改
import numpy as np
import panas as pd
dat = pd.DataFrame([{'Date': '07/01/2016', 'ID': 1, 'product':'A'},
{'Date': '07/01/2016', 'ID': 2, 'product':'B'},
{'Date': '07/01/2016', 'ID': 3, 'product':'D'},
{'Date': '07/04/2016', 'ID': 2, 'product':'F'},
{'Date': '07/05/2016', 'ID': 1, 'product':'G'},
{'Date': '07/09/2016', 'ID': 1, 'product':'K'},
{'Date': '07/09/2016', 'ID': 2, 'product':'L'},
{'Date': '07/09/2016', 'ID': 3, 'product':'X'},
{'Date': '07/11/2016', 'ID': 1, 'product':'N'},
{'Date': '07/13/2016', 'ID': 3, 'product':'M'},
{'Date': '07/17/2016', 'ID': 1, 'product':'Z'},
{'Date': '07/17/2016', 'ID': 2, 'product':'O'},
{'Date': '07/17/2016', 'ID': 3, 'product':'T'},])
dat.Date = pd.to_datetime(dat.Date, format="%m/%d/%Y")
print(dat)
Date ID product
0 2016-07-01 1 A
1 2016-07-01 2 B
2 2016-07-01 3 D
3 2016-07-04 2 F
4 2016-07-05 1 G
5 2016-07-09 1 K
6 2016-07-09 2 L
7 2016-07-09 3 X
8 2016-07-11 1 N
9 2016-07-13 3 M
10 2016-07-17 1 Z
11 2016-07-17 2 O
12 2016-07-17 3 T
现在,使用辅助函数
- calculate the time difference 在
Date
秒之间(根据 ID
)
- 计算周(0-7 天是第 1 周,7-14 天是第 2 周,依此类推)
然后,在每个组中(使用groupby
),use这两个辅助函数来计算时间和星期。由于您只需要每周(7 天)的第一个条目,执行第二个 groupby
并检索第一个记录。
这是将时间和星期计算为单独列的代码
- 用于计算
num_weeks
的代码来自此
dat = dat.sort_values(by=['ID','Date'])
dat['time'] = pd.Series()
dat['week'] = pd.Series([1]*len(dat))
def calc_time(df):
df.loc[:,'time'] = df['Date'] - df.loc[df.index.min(), 'Date']
num_weeks = (
int(np.ceil((dat['Date'].max() - \
dat['Date'].min())/np.timedelta64(1, 'W')))
)
df = calc_week(df, num_weeks) # num_weeks = 3
return df
def calc_week(df, num_weeks):
for week in range(1, num_weeks+1):
# print(str(week*7), str((week+1)*7))
df.loc[\
(df['time'] > str(week*7)+' days') & \
(df['time'] <= str((week+1)*7)+' days'), \
'week'] = week+1
return df
dat = dat.groupby(['ID']).apply(calc_time)
这是上面步骤的输出
print(dat)
Date ID product time week
0 2016-07-01 1 A 0 days 1
4 2016-07-05 1 G 4 days 1
5 2016-07-09 1 K 8 days 2
8 2016-07-11 1 N 10 days 2
10 2016-07-17 1 Z 16 days 3
1 2016-07-01 2 B 0 days 1
3 2016-07-04 2 F 3 days 1
6 2016-07-09 2 L 8 days 2
11 2016-07-17 2 O 16 days 3
2 2016-07-01 3 D 0 days 1
7 2016-07-09 3 X 8 days 2
9 2016-07-13 3 M 12 days 2
12 2016-07-17 3 T 16 days 3
现在,第二个 groupby
并排序以获得最终所需的输出
dat = dat.groupby(['ID','week']).first().reset_index(drop=False)
dff = (
dat[['Date','ID','product']].sort_values(by=['Date','ID'])
.reset_index(drop=True)
)
print(dff)
Date ID product
0 2016-07-01 1 A
1 2016-07-01 2 B
2 2016-07-01 3 D
3 2016-07-09 1 K
4 2016-07-09 2 L
5 2016-07-09 3 X
6 2016-07-17 1 Z
7 2016-07-17 2 O
8 2016-07-17 3 T
原始尝试
格式与 OP
相同
idx = pd.date_range('2018-04-01', '2018-05-01', freq='1D') + \
pd.DateOffset(days=16)
df = pd.DataFrame(idx, columns=['Date'])
df.set_index('Date', inplace=True)
df['ID'] = range(len(idx))
df['product'] = range(12,12+len(idx))
print(df)
ID product
Date
2018-04-17 0 12
2018-04-18 1 13
...
2018-05-16 29 41
2018-05-17 30 42
使用pd.data_range
只选择需要的区间
idx = pd.date_range(df.index[0], df.index[-1], freq='7D')
df_seven_days = df.loc[idx].reset_index(drop=False)
df_seven_days.rename(columns={'index': 'Date'}, inplace=True)
print(df_seven_days)
Date ID product
2018-04-17 0 12
2018-04-24 7 19
2018-05-01 14 26
2018-05-08 21 33
2018-05-15 28 40
我是 python 和 pandas 的新手,正在研究 pandas 数据框,这是一个 3 个月的数据,看起来像:
Date ID product
Jul-1 1 A
Jul-1 2 B
Jul-1 3 D
Jul-4 2 F
Jul-5 1 G
Jul-9 1 K
Jul-9 2 L
Jul-9 3 X
Jul-11 1 N
Jul-13 3 M
Jul-17 1 Z
Jul-17 2 O
Jul-17 3 T
我想做的是 select ID 仅在 7 天的增量,这样它就不会 select 任何 ID 如果它在接下来的 7 天内存在最后一次被采摘的日期。生成的数据框如下所示
Date ID product
Jul-1 1 A
Jul-1 2 B
Jul-1 3 D
Jul-9 1 K
Jul-9 2 L
Jul-9 3 X
Jul-17 1 Z
Jul-17 2 O
Jul-17 3 T
从早上开始就一直在尝试,非常感谢任何帮助
提前致谢!!
这样做:
dat = pd.DataFrame([{'Date': '01/02/2016', 'ID': 1, 'product':'A'},
{'Date': '01/02/2016', 'ID': 2, 'product':'B'},
{'Date': '01/04/2016', 'ID': 4, 'product':'C'},
{'Date': '01/05/2016', 'ID': 5, 'product':'D'},
{'Date': '01/06/2016', 'ID': 6, 'product':'a'},
{'Date': '01/07/2016', 'ID': 7, 'product':'b'},
{'Date': '01/09/2016', 'ID': 8, 'product':'d'},
{'Date': '01/09/2016', 'ID': 9, 'product':'A'},
{'Date': '01/16/2016', 'ID': 10, 'product':'B'},
{'Date': '01/18/2016', 'ID': 11, 'product':'C'},
{'Date': '01/18/2016', 'ID': 12, 'product':'K'},
{'Date': '01/21/2016', 'ID': 13, 'product':'J'},
{'Date': '01/25/2016', 'ID': 14, 'product':'I'},
{'Date': '01/25/2016', 'ID': 15, 'product':'H'},
{'Date': '01/25/2016', 'ID': 16, 'product':'G'},
{'Date': '01/30/2016', 'ID': 17, 'product':'F'}]) # Replace with your data
filtered_data = pd.DataFrame(columns=['Date', 'ID', 'product'])
dat.Date = pd.to_datetime(dat.Date, format="%m/%d/%Y") # Change the format as per your data
filtered_data.loc[len(filtered_data)] = dat.iloc[0]
def trans(row):
if (row.Date - filtered_data.tail(1).iloc[0].Date).days >= 7 or (row.Date - filtered_data.tail(1).iloc[0].Date).days == 0:
filtered_data.loc[len(filtered_data)] = row
dat.apply(trans, axis=1)
print filtered_data
结果:
Date ID product
0 2016-01-02 1 A
1 2016-01-02 1 A
2 2016-01-02 2 B
3 2016-01-09 8 d
4 2016-01-09 9 A
5 2016-01-16 10 B
6 2016-01-25 14 I
7 2016-01-25 15 H
8 2016-01-25 16 G
使用来自@suicidoteddy 的数据,稍作修改
import numpy as np
import panas as pd
dat = pd.DataFrame([{'Date': '07/01/2016', 'ID': 1, 'product':'A'},
{'Date': '07/01/2016', 'ID': 2, 'product':'B'},
{'Date': '07/01/2016', 'ID': 3, 'product':'D'},
{'Date': '07/04/2016', 'ID': 2, 'product':'F'},
{'Date': '07/05/2016', 'ID': 1, 'product':'G'},
{'Date': '07/09/2016', 'ID': 1, 'product':'K'},
{'Date': '07/09/2016', 'ID': 2, 'product':'L'},
{'Date': '07/09/2016', 'ID': 3, 'product':'X'},
{'Date': '07/11/2016', 'ID': 1, 'product':'N'},
{'Date': '07/13/2016', 'ID': 3, 'product':'M'},
{'Date': '07/17/2016', 'ID': 1, 'product':'Z'},
{'Date': '07/17/2016', 'ID': 2, 'product':'O'},
{'Date': '07/17/2016', 'ID': 3, 'product':'T'},])
dat.Date = pd.to_datetime(dat.Date, format="%m/%d/%Y")
print(dat)
Date ID product
0 2016-07-01 1 A
1 2016-07-01 2 B
2 2016-07-01 3 D
3 2016-07-04 2 F
4 2016-07-05 1 G
5 2016-07-09 1 K
6 2016-07-09 2 L
7 2016-07-09 3 X
8 2016-07-11 1 N
9 2016-07-13 3 M
10 2016-07-17 1 Z
11 2016-07-17 2 O
12 2016-07-17 3 T
现在,使用辅助函数
- calculate the time difference 在
Date
秒之间(根据ID
) - 计算周(0-7 天是第 1 周,7-14 天是第 2 周,依此类推)
然后,在每个组中(使用groupby
),use这两个辅助函数来计算时间和星期。由于您只需要每周(7 天)的第一个条目,执行第二个 groupby
并检索第一个记录。
这是将时间和星期计算为单独列的代码
- 用于计算
num_weeks
的代码来自此
dat = dat.sort_values(by=['ID','Date'])
dat['time'] = pd.Series()
dat['week'] = pd.Series([1]*len(dat))
def calc_time(df):
df.loc[:,'time'] = df['Date'] - df.loc[df.index.min(), 'Date']
num_weeks = (
int(np.ceil((dat['Date'].max() - \
dat['Date'].min())/np.timedelta64(1, 'W')))
)
df = calc_week(df, num_weeks) # num_weeks = 3
return df
def calc_week(df, num_weeks):
for week in range(1, num_weeks+1):
# print(str(week*7), str((week+1)*7))
df.loc[\
(df['time'] > str(week*7)+' days') & \
(df['time'] <= str((week+1)*7)+' days'), \
'week'] = week+1
return df
dat = dat.groupby(['ID']).apply(calc_time)
这是上面步骤的输出
print(dat)
Date ID product time week
0 2016-07-01 1 A 0 days 1
4 2016-07-05 1 G 4 days 1
5 2016-07-09 1 K 8 days 2
8 2016-07-11 1 N 10 days 2
10 2016-07-17 1 Z 16 days 3
1 2016-07-01 2 B 0 days 1
3 2016-07-04 2 F 3 days 1
6 2016-07-09 2 L 8 days 2
11 2016-07-17 2 O 16 days 3
2 2016-07-01 3 D 0 days 1
7 2016-07-09 3 X 8 days 2
9 2016-07-13 3 M 12 days 2
12 2016-07-17 3 T 16 days 3
现在,第二个 groupby
并排序以获得最终所需的输出
dat = dat.groupby(['ID','week']).first().reset_index(drop=False)
dff = (
dat[['Date','ID','product']].sort_values(by=['Date','ID'])
.reset_index(drop=True)
)
print(dff)
Date ID product
0 2016-07-01 1 A
1 2016-07-01 2 B
2 2016-07-01 3 D
3 2016-07-09 1 K
4 2016-07-09 2 L
5 2016-07-09 3 X
6 2016-07-17 1 Z
7 2016-07-17 2 O
8 2016-07-17 3 T
原始尝试
idx = pd.date_range('2018-04-01', '2018-05-01', freq='1D') + \
pd.DateOffset(days=16)
df = pd.DataFrame(idx, columns=['Date'])
df.set_index('Date', inplace=True)
df['ID'] = range(len(idx))
df['product'] = range(12,12+len(idx))
print(df)
ID product
Date
2018-04-17 0 12
2018-04-18 1 13
...
2018-05-16 29 41
2018-05-17 30 42
使用pd.data_range
只选择需要的区间
idx = pd.date_range(df.index[0], df.index[-1], freq='7D')
df_seven_days = df.loc[idx].reset_index(drop=False)
df_seven_days.rename(columns={'index': 'Date'}, inplace=True)
print(df_seven_days)
Date ID product
2018-04-17 0 12
2018-04-24 7 19
2018-05-01 14 26
2018-05-08 21 33
2018-05-15 28 40