对于程序中算法的小感想

估摸着程序还得跑个半小时,顺手写写今天碰到一件小事的感想。

一组DataFrame数据,columns有 [index, user_id, time_stamp],index无重复,user_id有重复,time_stamp是用户某一行为的时间戳且无序。

我要做一件事:计算同用户此刻时间戳与之前最近的时间戳之差,第一次行为时间戳直接记为-1。

比如:

index, user_id, time_stamp, time_diff

0, yanwu, 100, -1

1, yanwu , 130, 10

2, yanwu, 120, 20

因为time_stamp = 100的是最小的,意味着是第一次行为时间戳,标记为-1;

而下个最近的time_stamp  = 120,而120-100=20,所以差值为20;

同理130的这一行差值为130-120=10。

好,现在打算怎么做?



我第一个做法是这样:

两个for循环,第一个for里面找user_id,第二个for里面给user_id计算差值:

for i in set([user_id]):

      sort(i.[time_stamp]) //给i用户的时间戳排序

      for j in range(len(i.[time_stamp])):

                if j == 0:

                    time_diff = -1 //第一个的差值设置为-1

              else:

                      time_diff = i.[time_stamp][i] - i.[time_stamp] [i-1] //其余的差值就当前的减去上一个

很好理解吧,但是这个程序跑了我10小时... ... 因为我原数据接近100w条... ...

这么写,无非就是把我最真实的想法表现了出来,差值就是同一用户里时间戳两两相减,但是造成的结果呢?耗时耗力,强行用双重for遍历了这100w的数据。况且DataFrame中一条条遍历,已经蠢得不行了,这时候就必须考虑重新设计算法。是啊,跑了10小时才想起来修改算法... ... 真是血的教训... ...



我的第二个做法跑了不到1分钟,是这样的:

我最耗时间的是什么操作?遍历。

遍历是为了什么?给每一条数据做减法。

那能不能一次就减完呢?当然行啊。

首先我们确定一个东西,每一条数据该去减哪一条数据都是确定了的,已经有了确定的规则:“同一用户,上一条”。

sort_values(by=['user_id', 'time_tamp']) //通过user_id和timestamp为关键词排序

[tmp] =  ['time_tamp'][-1:].append([' time_tamp'][0:-1])  //创建一个新的数组型数据,内容按序设为time_stamp的倒数第一条加上前面所有条

[time_diff] = ['time_tamp'] - [tmp] //所有差值等于原时间戳列对应减去tmp

....... //最后通过groupby+rank找到每个user_id的第一条数据,将time_diff变为-1就是

看懂了吗?最核心的就第一个按两个关键字的排序,直接把确定的规则:“同一用户,上一条”给体现了出来。

按用户排序就直接把同一用户分在了一起,而给time_stamp排序则直接告诉我,减数与被减数,就是两两相邻的两条数据。

所以我直接减数这一列,也就是 ['time_tamp']不变,而被减数这一列数据就是减数['time_tamp']整体下移一条,然后两列数据对应相减,齐活,哪来什么遍历什么循环等等乱七八糟的,还10个小时呢.... ...



这只是个日常编程中的一个小插曲,但是给我感触挺深的, 少用for循环 虽然代码是表达人的思维,但是在表达思维的同时也要刻意注意算法的设计,毕竟算法是编程中很重要的一环,需要时刻注意去打磨去锻炼,否则... ... 否则... ... 否则... ... 哎,反正算法很重要!

对于程序中算法的小感想_第1张图片


(文章中的代码实属乱写,只是表达个基本意思;另外文章内容欢迎批评指正。)

你可能感兴趣的:(对于程序中算法的小感想)