在 Pig Latin 的多条件 RegExp 中使用 REPLACE
Use REPLACE in multicondition RegExp in Pig Latin
我有这组数据:
dump data;
这是一个样本输出:(这个数据集有将近一百万行)。
("0",60,0,1,"Fri")
("1",47,0,1,"Mon")
("1",23,1,0,"Tue")
("1",60,0,0,"Sat")
("1",50,1,1,"Fri")
我想将值:周六、周五、周一替换为周数,我知道如何使用 REPLACE 一次仅更改 1 个值,但我必须重复多次才能更改所有值星期几:
data_day_of_week = FOREACH data GENERATE [=12=],,,,REPLACE(, 'Mon', '1');
有什么方法可以只用一条语句做到这一点吗?
您应该使用 CASE WHEN THEN 语句
data_day_of_week = FOREACH data GENERATE
CASE
WHEN == 'Mon' THEN '1'
WHEN == 'Tue' THEN '2'
...
WHEN == 'Sun' THEN '7'
END AS day_number;
您还应该命名您的关系,以免使用 $1、$2 等。如果您将 $4 命名为 day_number,那么当您从 CASE 语句中将变量声明为 day_number 时,它将“覆盖”您之前的数据。
您可以将 JOIN 与对映射的引用一起使用,如下所示:
(Mon,1)
(Tue,2)
(Wed,3)
(Thu,4)
(Fri,5)
(Sat,6)
(Sun,7)
加入语句:
outer_left = join your_data by left outer, day_mapping by day;
您可以组合 Pig ToDate 和 ToString 函数:
data_day_of_week = FOREACH data GENERATE [=10=],,,,
ToString(ToDate(, 'EEE'), 'e') as day_of_week;
ToDate functions will convert the chararray day of the week to a Pig date time format. Then ToString 会将其转换为您选择的格式。
根据 Java docs 单个 e 或 c 应该给出星期几的数字格式,其中星期一为 1。
saph_top,是最接近回答我的问题的人,但是在测试它解决了空白输出之后,我将补充他的回答:
'Mon' 与“Mon”不同,因此当我使用时:CASE WHEN $4 == 'Mon' THEN '1' 它没有替换任何东西,导致空白结果在:data_day_of_week.
为了解决这个问题,我只需要添加“”(条件的双引号):
data_day_of_week = FOREACH data GENERATE
CASE
WHEN == '"Mon"' THEN '1'
WHEN == '"Tue"' THEN '2'
...
WHEN == '"Sun"' THEN '7'
END AS day_number;
之后,为了重建数据,我将以下内容添加到 GENERATE 子句中:
data_day_of_week = FOREACH data GENERATE [=11=],,,,
CASE
WHEN == '"Mon"' THEN '1'
WHEN == '"Tue"' THEN '2'
...
WHEN == '"Sun"' THEN '7'
END AS day_number;
现在输出已经完成:
转储data_day_of_week;
("0",60,0,1,5)
("1",47,0,1,1)
("1",23,1,0,2)
("1",60,0,0,6)
("1",50,1,1,5)
我有这组数据:
dump data;
这是一个样本输出:(这个数据集有将近一百万行)。
("0",60,0,1,"Fri")
("1",47,0,1,"Mon")
("1",23,1,0,"Tue")
("1",60,0,0,"Sat")
("1",50,1,1,"Fri")
我想将值:周六、周五、周一替换为周数,我知道如何使用 REPLACE 一次仅更改 1 个值,但我必须重复多次才能更改所有值星期几:
data_day_of_week = FOREACH data GENERATE [=12=],,,,REPLACE(, 'Mon', '1');
有什么方法可以只用一条语句做到这一点吗?
您应该使用 CASE WHEN THEN 语句
data_day_of_week = FOREACH data GENERATE
CASE
WHEN == 'Mon' THEN '1'
WHEN == 'Tue' THEN '2'
...
WHEN == 'Sun' THEN '7'
END AS day_number;
您还应该命名您的关系,以免使用 $1、$2 等。如果您将 $4 命名为 day_number,那么当您从 CASE 语句中将变量声明为 day_number 时,它将“覆盖”您之前的数据。
您可以将 JOIN 与对映射的引用一起使用,如下所示:
(Mon,1)
(Tue,2)
(Wed,3)
(Thu,4)
(Fri,5)
(Sat,6)
(Sun,7)
加入语句:
outer_left = join your_data by left outer, day_mapping by day;
您可以组合 Pig ToDate 和 ToString 函数:
data_day_of_week = FOREACH data GENERATE [=10=],,,,
ToString(ToDate(, 'EEE'), 'e') as day_of_week;
ToDate functions will convert the chararray day of the week to a Pig date time format. Then ToString 会将其转换为您选择的格式。
根据 Java docs 单个 e 或 c 应该给出星期几的数字格式,其中星期一为 1。
saph_top,是最接近回答我的问题的人,但是在测试它解决了空白输出之后,我将补充他的回答:
'Mon' 与“Mon”不同,因此当我使用时:CASE WHEN $4 == 'Mon' THEN '1' 它没有替换任何东西,导致空白结果在:data_day_of_week.
为了解决这个问题,我只需要添加“”(条件的双引号):
data_day_of_week = FOREACH data GENERATE
CASE
WHEN == '"Mon"' THEN '1'
WHEN == '"Tue"' THEN '2'
...
WHEN == '"Sun"' THEN '7'
END AS day_number;
之后,为了重建数据,我将以下内容添加到 GENERATE 子句中:
data_day_of_week = FOREACH data GENERATE [=11=],,,,
CASE
WHEN == '"Mon"' THEN '1'
WHEN == '"Tue"' THEN '2'
...
WHEN == '"Sun"' THEN '7'
END AS day_number;
现在输出已经完成: 转储data_day_of_week;
("0",60,0,1,5)
("1",47,0,1,1)
("1",23,1,0,2)
("1",60,0,0,6)
("1",50,1,1,5)