我正在尝试比较日期以在两个熊猫数据框中设置标记,并按item_ids进行分组。我的两个数据帧如下:
df_1包含所有item_id,并为每个item_id列出该项目在生产中的哪个季度:
df_1 =
item_id qtr
0 X1 2016-06-01
1 X1 2016-09-01
2 X1 2017-01-01
3 X1 2017-03-01
4 X1 2017-06-01
5 X1 2017-09-01
6 X1 2018-01-01
7 X1 2018-03-01
8 X1 2018-06-01
9 X1 2018-09-01
10 X1 2019-01-01
11 X1 2019-03-01
12 X1 2019-06-01
13 X2 2016-06-01
14 X2 2016-09-01
15 X2 2017-01-01
16 X2 2017-03-01
17 X2 2017-06-01
18 X2 2017-09-01
19 X3 2018-03-01
20 X3 2018-06-01
21 X3 2018-09-01
22 X3 2019-01-01
23 X3 2019-03-01
24 X3 2019-06-01
df_2按item_id列出错误,并列出错误的开始日期和结束日期以及错误代码:
df_2=
item_id error_num start_date end_date code
0 X1 1 2016-11-05 2017-04-16 A
1 X1 2 2018-12-18 2019-03-09 B
2 X2 1 2017-02-04 2017-05-17 C
3 X3 1 2018-08-11 2019-02-20 B
对于df_1中的每个item_id,我需要检查qtr日期是否在该项目的任何错误的start_date和end_date之间,然后返回一个标志以指示是否存在错误,error_num和代码。输出应如下所示:
item_id qtr error error_num code
0 X1 2016-06-01 0 N/A N/A
1 X1 2016-09-01 0 N/A N/A
2 X1 2017-01-01 1 1 A
3 X1 2017-03-01 1 1 A
4 X1 2017-06-01 0 N/A N/A
5 X1 2017-09-01 0 N/A N/A
6 X1 2018-01-01 0 N/A N/A
7 X1 2018-03-01 0 N/A N/A
8 X1 2018-06-01 0 N/A N/A
9 X1 2018-09-01 0 N/A N/A
10 X1 2019-01-01 1 2 B
11 X1 2019-03-01 1 2 B
12 X1 2019-06-01 0 N/A N/A
13 X2 2016-06-01 0 N/A N/A
14 X2 2016-09-01 0 N/A N/A
15 X2 2017-01-01 0 N/A N/A
16 X2 2017-03-01 1 1 C
17 X2 2017-06-01 0 N/A N/A
18 X2 2017-09-01 0 N/A N/A
19 X3 2018-03-01 0 N/A N/A
20 X3 2018-06-01 0 N/A N/A
21 X3 2018-09-01 1 1 B
22 X3 2019-01-01 1 1 B
23 X3 2019-03-01 0 N/A N/A
24 X3 2019-06-01 0 N/A N/A
我可以使用嵌套的for循环获得所需的结果,但是我的完整矩阵中有成千上万的项目,我估计使用我的当前方法要花费数天或数周的时间。这是我当前的代码:
item_ids = df_1.item_id.unique()
err_flags = pd.DataFrame(columns = ['item_id', 'qtr', 'error', 'error_num', 'code'])
for item_id in item_ids:
item_id_dates = df_1.loc[df_1['item_id']==item_id]
item_id_errs = df_2.loc[df_2['item_id']==item_id]
for row in item_id_errs.itertuples(index = True, name = 'Pandas'):
start_date = getattr(row, 'start_date')
end_date = getattr(row, 'end_date')
err_num = getattr(row, 'error_num')
err_code = getattr(row, 'code')
item_id_dates.loc[(item_id_dates.qtr >= start_date) & (item_id_dates.qtr <= end_date), 'error'] = 1
item_id_dates.loc[(item_id_dates.qtr >= start_date) & (item_id_dates.qtr <= end_date), 'error_num'] = err_num
item_id_dates.loc[(item_id_dates.qtr >= start_date) & (item_id_dates.qtr <= end_date), 'code'] = err_code
err_flags = err_flags.append(item_id_dates, ignore_index = True)
err_flags = err_flags[['item_id', 'qtr', 'error', 'error_num', 'code']]
values = {'error': 0, 'error_num': 'N/A', 'code': 'N/A'}
err_flags = err_flags.fillna(values)
我对python还是很陌生,但是我知道足够多,这可能是效率最低的方法。我曾尝试研究列表理解或矢量化方法,但很难找到包含类似分组类型的示例。