我有一个包含超过 10,000 条记录的交通机构的每日智能卡交易数据集。我正在尝试创建一个名为 transfer
的列,用于指示交易是否为转移。我创建了一个模拟数据集:
mock_df = pd.DataFrame({
'cardNumber': ['100', '100', '100', '200', '300', '300', '300'],
'type': ['DAILY_CAP_REACHED', 'DAILY_CAP_REACHED', 'DAILY_CAP_REACHED', 'DAILY_CAP_REACHED',
'DAILY_CAP_REACHED', 'DAILY_CAP_REACHED', 'DAILY_CAP_REACHED'],
'date_only': ['2021/05/01', '2021/05/01', '2021/05/01', '2021/05/01', '2021/05/04', '2021/05/04', '2021/05/04'],
'time_only': ['17:15', '17:45', '18:15', '12:15', '13:15', '17:45', '18:15'],
'fare': [250, 0, 0, 250, 250, 0, 0]
})
产生下表。
cardNumber type date_only time_only fare
0 100 DAILY_CAP_REACHED 2021/05/01 17:15 250
1 100 DAILY_CAP_REACHED 2021/05/01 17:45 0
2 100 DAILY_CAP_REACHED 2021/05/01 18:15 0
3 200 DAILY_CAP_REACHED 2021/05/01 12:15 250
4 300 DAILY_CAP_REACHED 2021/05/04 13:15 250
5 300 DAILY_CAP_REACHED 2021/05/04 17:45 0
6 300 DAILY_CAP_REACHED 2021/05/04 18:15 0
乘客每天有 90 分钟的时间从第一笔交易开始进行转乘。因此,如果自第一次交易以来已经过去了 90 分钟以上,则不应将其记录为转账。 我希望有一个如下所示的数据框:
cardNumber type date_only time_only fare transfer
0 100 DAILY_CAP_REACHED 2021/05/01 17:15 250 N
1 100 DAILY_CAP_REACHED 2021/05/01 17:45 0 Y
2 100 DAILY_CAP_REACHED 2021/05/01 18:15 0 Y
3 200 DAILY_CAP_REACHED 2021/05/01 12:15 250 N
4 300 DAILY_CAP_REACHED 2021/05/04 13:15 250 N
5 300 DAILY_CAP_REACHED 2021/05/04 17:45 0 N
6 300 DAILY_CAP_REACHED 2021/05/04 18:15 0 Y
答案 0 :(得分:1)
您可以使用:
mock_df['datetime'] = pd.to_datetime(mock_df['date_only'] + ' ' + mock_df['time_only'])
mock_df['transfer'] = np.where(mock_df.groupby('cardNumber')['datetime'].diff() <= pd.Timedelta(minutes=90), 'Y', 'N')
结果:
print(mock_df)
cardNumber type date_only time_only fare datetime transfer
0 100 DAILY_CAP_REACHED 2021/05/01 17:15 250 2021-05-01 17:15:00 N
1 100 DAILY_CAP_REACHED 2021/05/01 17:45 0 2021-05-01 17:45:00 Y
2 100 DAILY_CAP_REACHED 2021/05/01 18:15 0 2021-05-01 18:15:00 Y
3 200 DAILY_CAP_REACHED 2021/05/01 12:15 250 2021-05-01 12:15:00 N
4 300 DAILY_CAP_REACHED 2021/05/04 13:15 250 2021-05-04 13:15:00 N
5 300 DAILY_CAP_REACHED 2021/05/04 17:45 0 2021-05-04 17:45:00 N
6 300 DAILY_CAP_REACHED 2021/05/04 18:15 0 2021-05-04 18:15:00 Y
答案 1 :(得分:0)
我正在阅读的关键部分是这个要求:
“如果自第一次交易以来已经过去了 90 分钟以上,则不应将其记录为转账。”
因此,仅与前一次相比是不够的,因为 3 笔交易中的每笔交易之间可能不到 90 分钟,但第一笔和最后一笔之间的时间可能超过 90 分钟,从而使其成为非转移。
这种方法会奏效,尽管可能有办法让它更漂亮一些:
mock_df['datetime'] = pd.to_datetime(mock_df['date_only'] + ' ' + mock_df['time_only'])
for grp_idx,grp in mock_df.groupby('cardNumber'):
for i,(idx,dt) in enumerate(grp['datetime'].iteritems()):
if i==0:
dt_comp = dt
mock_df.at[idx,'transfer'] = 'N'
else:
if dt-dt_comp < pd.Timedelta(minutes=90):
mock_df.at[idx,'transfer'] = 'Y'
else:
mock_df.at[idx,'transfer'] = 'N'
dt_comp = dt
编辑:添加结果
cardNumber type date_only time_only fare \
0 100 DAILY_CAP_REACHED 2021/05/01 17:15 250
1 100 DAILY_CAP_REACHED 2021/05/01 17:45 0
2 100 DAILY_CAP_REACHED 2021/05/01 18:15 0
3 200 DAILY_CAP_REACHED 2021/05/01 12:15 250
4 300 DAILY_CAP_REACHED 2021/05/04 13:15 250
5 300 DAILY_CAP_REACHED 2021/05/04 17:45 0
6 300 DAILY_CAP_REACHED 2021/05/04 18:15 0
datetime transfer
0 2021-05-01 17:15:00 N
1 2021-05-01 17:45:00 Y
2 2021-05-01 18:15:00 Y
3 2021-05-01 12:15:00 N
4 2021-05-04 13:15:00 N
5 2021-05-04 17:45:00 N
6 2021-05-04 18:15:00 Y