indexing - SAS 尝试在小样本数据集上使用哈希表进行模糊匹配时内存不足
问题描述
我有一个大约 5,000,000 行的姓名、电话号码和地址列表。我正在尝试在每个地址创建一个唯一客户列表,并为每个唯一客户分配一个密钥。客户名称的格式不一致,因此 John Smith 可能显示为 Smith、John 或 John Smith Jr. 等。
我要遵循的逻辑是这样的:
如果一个地址的两条记录具有相同的电话号码,则它是同一个客户,无论他们是否具有不同的名称,并分配相同的 customer_key。
如果一个地址的两条记录没有相同的电话号码(或没有电话号码),但他们的名字的模糊匹配超过了某个阈值,则它们是同一个客户,并被分配相同的 customer_key。
请注意,在两个不同地址匹配的相同客户名称 + 电话号码不应分配相同的客户密钥。
以下是包含示例输入和所需输出的示例表:
https://docs.google.com/spreadsheets/d/1RsABSFy5a5dLE8mC-ZQF_lNg4I0kLQy7dEFhbfovq40/edit?usp=sharing
我使用此示例数据集的代码尝试如下:
data customer_keys(keep=customer_name customer_key customer_phone clean_address);
length customer_name $50 Comp_Name $20 customer_key 8 clean_address comp_address $5 customer_phone comp_phone $11.;
if _N_ = 1 then do;
declare hash h(multidata:'Y');
h.defineKey('Comp_Name','comp_address');
h.defineData('Comp_Name', 'customer_key','comp_address', 'comp_phone');
h.defineDone();
declare hiter hi('h');
declare hash hh(multidata:'Y');
hh.defineKey('customer_key');
hh.defineData('customer_key', 'Comp_Name','comp_address','comp_phone');
hh.defineDone();
_customer_key=0;
end;
set testdat;
rc=h.find(key:customer_name, key:clean_address);
if rc ne 0 then do;
rc=hi.first();
do while (rc=0);
if not missing(customer_phone) and clean_address=comp_address and customer_phone=comp_phone
then do;
h.add(key:customer_name,key:clean_address, data:customer_name, data:customer_key, data:clean_address, data:customer_phone);
hh.add();
end;
else if not missing(customer_name) and clean_address=comp_address and jaroT(customer_name,Comp_name) ge 0.8
then do;
rc=hh.find();
do while (r ne 0);
dist2=jaroT(customer_name,Comp_name);
hh.has_next(result:r);
if r=0 & dist2 ge 0.8 then do;
h.add(key:customer_name,key:clean_address, data:customer_name, data:customer_key, data:clean_address, data:customer_phone);
hh.add();
output;return;
end;
else if r ne 0 & dist2 ge 0.8
then rc=hh.find_next();
else if dist2 < 0.8
then leave;
end;
end;
rc=hi.next();
end;
_customer_key+1;
customer_key=_customer_key;
h.add(key:customer_name,key:clean_address, data:customer_name, data:customer_key, data:clean_address, data:customer_phone);
hh.add(key:customer_key, data:customer_key, data:customer_name, data:clean_address, data:customer_phone);
end;
output;
run;
运行此代码会产生错误:
ERROR: Hash object added 23068656 items when memory failure occurred.
FATAL: Insufficient memory to execute DATA step program. Aborted during the EXECUTION phase.
ERROR: The SAS System stopped processing this step because of insufficient memory.
我注意到,如果我完全删除处理电话号码的附加逻辑,我就没有这个内存问题。但是,当我尝试在完整数据集上运行它时,我仍然会假设我的方法会因为内存不足而失败。
解决方案
在您的 Windows 搜索功能中搜索“sas.exe-memsize 16G”以提取新版本的 sas 程序,该程序将具有 16G 的内存存储。您也可以更改 G 之前的数字。还要确保您有足够的磁盘空间。干杯。
推荐阅读
- prometheus - 为什么创建临时变量时未列出我的数据源?
- r - 将时间从 1 小时更改为 30 分钟
- wordpress - 使用函数maybe_unserialize从字符串中反序列化数据
- php - 无法反转属性路径 [...] 的值:选项 [...] 不存在或不唯一
- java - 如何从 Java 中的映射器方法返回不同的类型?
- javascript - 尝试编写简单的 html 页面以在按下按钮时播放语音时出现问题
- 3d - 如何在 3D 空间中放置一个垂直于表面的对象?
- c++ - std::chrono::duration::count 返回什么?
- android - 使用 Moshi JsonWriter 序列化未知的任何 / 对象
- javascript - 如何在Javascript(ES6)中缩短此功能