文本消息中字符串的猪计数出现

Posted

技术标签:

【中文标题】文本消息中字符串的猪计数出现【英文标题】:Pig count occurrence of strings in text messages 【发布时间】:2013-11-06 21:27:06 【问题描述】:

我有两个文件——venues.csv 和 tweets.csv。我想计算每个场所在推文文件中的推文消息中出现的次数。

我已经在 HCatalog 中导入了 csv 文件。

到目前为止我所做的事情:

我知道如何过滤text 字段并获取这些包含'Shell' 推文消息的元组。我想做同样的事情,但不是硬编码的Shell,而是venuesNames包中的每个name。我怎样才能做到这一点?另外,如何正确使用generate 命令生成一个新包,将计数结果与场地名称相匹配?

a = LOAD 'venues_test_1' USING org.apache.hcatalog.pig.HCatLoader();
b = LOAD 'tweets_test_1' USING org.apache.hcatalog.pig.HCatLoader();

venuesNames = foreach a generate name;

countX = FILTER b BY (text matches '.*Shell.*');

venueToCount = generate ('Shell' as venue, COUNT(countX) as countVenues); 

DUMP venueToCount;

我使用的文件是:

tweets.csv

created_at,text,location
Sat Nov 03 13:31:07 +0000 2012, Sugar rush dfsudfhsu, Glasgow
Sat Nov 03 13:31:07 +0000 2012, Sugar rush ;dfsosjfd HAHAHHAHA, London
Sat Apr 25 04:08:47 +0000 2009, at Sugar rush dfjiushfudshf, Glasgow
Thu Feb 07 21:32:21 +0000 2013, Shell gggg, Glasgow
Tue Oct 30 17:34:41 +0000 2012, Shell dsiodshfdsf, Edinburgh
Sun Mar 03 14:37:14 +0000 2013, Shell wowowoo, Glasgow
Mon Jun 18 07:57:23 +0000 2012, Shell dsfdsfds, Glasgow
Tue Jun 25 16:52:33 +0000 2013, Shell dsfdsfdsfdsf, Glasgow

venues.csv

city,name
Glasgow, Sugar rush
Glasgow, ABC
Glasgow, University of Glasgow
Edinburgh, Shell
London, Big Ben

我知道这些是基本问题,但我刚刚开始使用 Pig,我们将不胜感激!

【问题讨论】:

我在您的示例中看到您有一条类似“Shell...Glasgow”的推文,尽管在您的 venus 文件中您指出 Shell 在爱丁堡。你想要求城市匹配吗?或者任何带有场地名称的推文都算数,无论它是在哪里发送的? @WinnieNicklaus 好吧,起初我正在寻找最简单的大多数情况,所以我很乐意计算每个地点的时间 - 推文消息中出现了多少时间。例如,Shell 出现在 5 条推特消息中。 【参考方案1】:

我认为您的场地名称列表是独一无二的。如果不是,那么无论如何您都会遇到更多问题,因为您需要消除正在谈论的地点的歧义(也许通过参考城市字段)。但忽略这种潜在的并发症,您可以这样做:

您已经描述了一个模糊连接。在 Pig 中,如果无法强制记录包含标准值(在这种情况下,必须使用 UDF),您需要使用 CROSS 运算符。请谨慎使用,因为如果您将两个关系与 MN 记录交叉,结果将是与 M*N 记录的关系,这可能超出您的系统可以处理的范围。

一般策略是 1) CROSS 两个关系,2) 为每条记录创建自定义正则表达式*,以及 3) 过滤那些通过正则表达式的。

venues = LOAD 'venues_test_1' USING org.apache.hcatalog.pig.HCatLoader();
tweets = LOAD 'tweets_test_1' USING org.apache.hcatalog.pig.HCatLoader();

/* Create the Cartesian product of venues and tweets */
crossed = CROSS venues, tweets;
/* For each record, create a regex like '.*name.*'
regexes = FOREACH crossed GENERATE *, CONCAT('.*', CONCAT(venues::name, '.*')) AS regex;
/* Keep tweet-venue pairs where the tweet contains the venue name /*
venueMentions = FILTER regexes BY text MATCHES regex;

venueCounts = FOREACH (GROUP venueMentions BY venues::name) GENERATE group, COUNT($1);

如果某些推文提到多个地点,所有venueCounts 的总和可能会超过推文的数量。

*请注意,您必须小心使用此技术,因为如果场地名称包含在 Java 正则表达式中具有特殊解释的字符,则需要对它们进行转义。

【讨论】:

谢谢!您的解决方案正在运行,但它仅适用于少量输入。您是否认为有另一种方法不创建这两个关系的笛卡尔积?

以上是关于文本消息中字符串的猪计数出现的主要内容,如果未能解决你的问题,请参考以下文章

计算某些文本中多字串的出现次数

两个表之间的猪拉丁计数差异

计算文本文件中出现的所有字符

使用Counter进行计数统计

从文本字符串中获取字符串的唯一计数

带字符串的猪代数