根据熊猫中的订单顺序分配分数

时间:2020-03-16 13:32:11

标签: pandas

以下是我拥有的数据框

score_df

col1_id col2_id score
1 2 10
5 6 20

records_df

date col_id 
D1    6
D2    4
D3    1
D4    2
D5    5
D6    7

我想根据以下标准计算分数:

当2在1之后出现时,分数应指定为10,或者当1在2之后出现时,分数应分配为10。

即,当(1,2)的得分为10 ..(2,1)时,得分也为10。

考虑(1,2)。第一次出现1时,我们不分配分数。我们标记该行并等待2发生。当该列中出现2时,我们给分数10。

考虑(2,1)。当2首先出现时。我们指定值0,然后等待1出现。当出现1时,我们给分数10。

所以,第一次-不要分配分数,等待相应的事件发生,然后分配分数

因此,我的结果数据框应如下所示

结果

date col_id score
D1    6     0 -- Eventhough 6 is there in score list, it occured for first time. So 0
D2    4     0 -- 4 is not even there in list
D3    1     0 -- 1 occurred for first time . So 0
D4    2     10 -- 1 occurred previously. 2 occurred now.. we can assign 10. 
D5    5     20 -- 6 occurred previously. we can assign 20
D6    7     0 -- 7 is not in the list

我在score_df和record_df中都有大约10万行。循环和分配分数很费时间。有人可以在不循环整个数据帧的情况下提供逻辑帮助吗?

1 个答案:

答案 0 :(得分:2)

据我了解,您可以尝试melt进行取消透视,然后尝试merge。保持索引与融化的df相同,我们检查where的索引为duplicated,然后从合并返回0。

m = score_df.reset_index().melt(['index','uid','score'],
                              var_name='col_name',value_name='col_id')

final = records_df.merge(m.drop('col_name',1),on=['uid','col_id'],how='left')

c = final.duplicated(['index']) & final['index'].notna()
final = final.drop('index',1).assign(score=lambda x: x['score'].where(c,0))

print(final)

   uid date  col_id  score
0  123   D1       6    0.0
1  123   D2       4    0.0
2  123   D3       1    0.0
3  123   D4       2   10.0
4  123   D5       5   20.0
5  123   D6       7    0.0