我有一个像下面这样的数据集
Customer_ID Vistited_Date
1234 7-Feb-20
4567 7-Feb-20
9870 7-Feb-20
1234 14-Feb-20
7654 14-Feb-20
3421 14-Feb-20
我正在尝试按日期查找累积的唯一客户数,假设我的输出如下所示
Cust_count Vistited_Date
3 7-Feb-20
2 14-Feb-20
2020年2月7日有3个唯一的客户,而 2020年2月14日只有2个,因此客户1234已经造访了 。
任何人都知道在这种情况下如何开发数据集吗?
很抱歉,我的问题还不够清楚,如有必要,我可以提供更多详细信息。
谢谢!
答案 0 :(得分:3)
注意:@draycut的答案具有相同的逻辑,但速度更快,我将解释原因。
@draycut的代码使用一种哈希方法add()
,将返回码用作条件增量的测试。我的代码使用check()
测试条件增量,然后使用add
(永远不会失败)进行跟踪。可以认为一种方法可以将性能提高15%到40%(取决于组的数量,组的大小和ID重用率)
您将需要跟踪所有先前组中发生的ID
,并从当前组计数中排除跟踪的ID
。
可以使用hash
进行跟踪,并且可以在每个组的 DOW 循环中执行条件计数。 DOW循环将SET
语句放在显式DO
内。
示例:
data have;
input ID Date: date9.; format date date11.;
datalines;
1234 7-Feb-20
4567 7-Feb-20
9870 7-Feb-20
1234 14-Feb-20
7654 14-Feb-20
3421 14-Feb-20
;
data counts(keep=date count);
if _n_ = 1 then do;
declare hash tracker();
tracker.defineKey('id');
tracker.defineDone();
end;
do until (last.date);
set have;
by date;
if tracker.check() ne 0 then do;
count = sum(count, 1);
tracker.add();
end;
end;
run;
原始性能基准-进行散列之前不需要磁盘io,cpu来填充数组,因此将这些性能组件组合在一起。
根性能是将新项目添加到哈希中的速度。
模拟3,000,000个“记录”,其中3,000 groups
个中的1,000 dates
,ID重用率为10%(因此,不同的ID将为〜2.7M)。
%macro array_fill (top=3000000, n_group = 1000, overlap_factor=0.10);
%local group_size n_overlap index P Q;
%let group_size = %eval (&top / &n_group);
%if (&group_size < 1) %then %let group_size = 1;
%let n_overlap = %sysevalf (&group_size * &overlap_factor, floor);
%if &n_overlap < 0 %then %let n_overlap = 0;
%let top = %sysevalf (&group_size * &n_group);
P = 1;
Q = &group_size;
array ids(&top) _temporary_;
_n_ = 0;
do i = 1 to &n_group;
do j = P to Q;
_n_+1;
ids(_n_) = j;
end;
P = Q - &n_overlap;
Q = P + &group_size - 1;
end;
%mend;
options nomprint;
data _null_ (label='check then add');
length id 8;
declare hash h();
h.defineKey('id');
h.defineDone();
%array_fill;
do index = 1 to dim(ids);
id = ids(index);
if h.check() ne 0 then do;
count = sum(count,1);
h.add();
end;
end;
_n_ = h.num_items;
put 'num_items=' _n_ comma12.;
put index= comma12.;
stop;
run;
data _null_ (label='just add');
length id 8;
declare hash h();
h.defineKey('id');
h.defineDone();
%array_fill;
do index = 1 to dim(ids);
id = ids(index);
if h.add() = 0 then
count = sum(count,1);
end;
_n_ = h.num_items;
put 'num_items=' _n_ comma12.;
put index= comma12.;
stop;
run;
答案 1 :(得分:3)
import os
import time
from datetime import datetime
dat =['Fri May 29 20:47:53 2020']
for i in dat:
print(datetime.strptime(i,'%a %B %d %H:%M:%S %Y').date())
答案 2 :(得分:2)
如果您的数据未排序并且您喜欢SQL,则此解决方案对您同样有好处,而且非常简单:
/* your example 3 rows */
data have;
input ID Date: date9.; format date date11.;
datalines;
1234 7-Feb-20
4567 7-Feb-20
9870 7-Feb-20
1234 14-Feb-20
7654 14-Feb-20
3421 14-Feb-20
1234 15-Feb-20
7654 15-Feb-20
1111 15-Feb-20
;
run;
/* simple set theory. Final dataset contains your final data like results
below*/
proc sql;
create table temp(where =(mindate=date)) as select
ID, date,min(date) as mindate from have
group by id;
create table final as select count(*) as customer_count,date from temp
group by date;
quit;
/* results:
customer_count Date
3 07.febr.20
2 14.febr.20
1 15.febr.20
*/
答案 3 :(得分:1)
另一种方法,因为我不太了解哈希。 > _ << / p>
data have;
input ID Date: date9.; format date date11.;
datalines;
1234 7-Feb-20
4567 7-Feb-20
9870 7-Feb-20
1234 14-Feb-20
7654 14-Feb-20
3421 14-Feb-20
;
data want;
length Used $200.;
retain Used;
set have;
by Date;
if first.Date then count = .;
if not find(Used,cats(ID)) then do;
count + 1;
Used = catx(',',Used,ID);
end;
if last.Date;
put Date= count=;
run;
答案 4 :(得分:1)
如果您对处理速度不是很在意,并希望简单一些:
proc sort data=have;
by id date;
** Get date of each customer's first unique visit **;
proc sort data=have out=first_visit nodupkey;
by id;
proc freq data=first_visit noprint;
tables date /out=want (keep=date count);
run;