用于计算 emp 时间的最小值、最大值的 Pig 脚本
Pig Script to compute Min, Max of emp timings
我是 Pig 和 Hadoop 世界的新手。我遇到的问题可能很简单,但我无法继续。
所以我有下面的数据,基本上是一天的数据。
我需要计算员工一天花费的总小时数,即使用 PIG 的第一个上班时间(他到达办公室的时间)和最后一个下班时间(当天最后一次刷卡)之间的差异。
EmpID In_Time Out_Time
1 9:00 10:00
2 8:00 11:00
3 10:00 12:00
1 11:00 13:00
1 14:00 18:00
2 12:00 18:00
3 13:00 18:00
所以我写了下面的脚本,但它似乎没有给出正确的结果。
grunt> emprec = load '/emptime/emptime' using PigStorage() as (empid:int,in:chararray,out:chararray);
grunt> aggdata = group emprec by empid;
grunt> emptime = foreach aggdata generate (emprec.empid,MIN(emprec.in),MAX(emprec.out));
我写的脚本似乎没有得到正确的结果。
我需要的结果是
中间结果(我的理解)
EmpID In_Time Out_Time
1 9:00 18:00
2 8:00 18:00
3 10:00 18:00
所需的最终输出是 Out_Time-In_Time
的差异
EmpID Total_Time
1 9:00
2 10:00
3 8:00
我写了最后一行来获取最小和最大时间,这样我就可以减去 2 并得到在办公室花费的总时间
请注意,如果您想将时间假定为 Int 或任何其他格式,请这样做,因为这只是一个示例。
提前致谢
此致,
车坛
在 chararray
数据类型上使用 MAX
、MIN
没有给您预期的结果。如果你想避免写 UDF
你可以按照这个解决方案:
我从数据开始:
1,9:00,10:00
2,8:00,11:00
3,10:00,12:00
1,11:00,13:00
1,14:00,18:00
2,12:00,18:00
3,13:00,18:00
emprec = load '/home/cloudera/pig.txt' using PigStorage(',') as (empid:int,in:chararray,out:chararray);
cleandata = foreach emprec generate [=11=] as ID ,(double)REPLACE(,':','.') as in_time,(double)REPLACE(,':','.') as out_time; --convert time to double so you can use eval functions on it
aggdata = group cleandata by ID;
emptime = foreach aggdata generate group ,MIN(cleandata.in_time),MAX(cleandata.out_time);
results = foreach emptime generate [=11=] as Emp_ID,REPLACE((chararray)( - ),'\.(?s)','\:0') as time_diff; --convert back to time
dump results;
输出:
(1,9:00)
(2,10:00)
(3,8:00)
如果您有兴趣创建 Pig UDF,那么这里是代码:
package Conversion;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
public class ConvertDot extends EvalFunc<String> {
@Override
public String exec(Tuple input) throws IOException {
String newstr = new String();
if(input == null || input.size() == 0)
return null;
try{
String str = (String)input.get(0);
if(str.contains(":"))
newstr = str.replace(':','.');
else if(str.contains("."))
newstr = str.replace('.',':');
else
newstr = str;
}catch (Exception e){
throw new IOException("Caught exception ", e);
}
return newstr;
}
}
$ cat ComputeTotalTime.pig
--Calculate Min, Man and Total time
REGISTER /home/hadoop/Desktop/Abhinav/ConvertDotColon.jar
emprec = LOAD '/home/hadoop/Desktop/Abhinav/swaptime.txt' USING PigStorage(',') AS (empid:int, in:chararray, out:chararray);
cleandata = FOREACH emprec GENERATE empid, (double)Conversion.ConvertDot(in) as in, (double)Conversion.ConvertDot(out) as out;
aggdata = group cleandata by empid;
emptime = foreach aggdata generate group, MIN(cleandata.in), MAX(cleandata.out);
results = foreach emptime generate [=10=] as EmpId, Conversion.ConvertDot((chararray)( - )) as Time_diff;
STORE results INTO '/home/hadoop/Desktop/Abhinav/TotalTime.txt';
我是 Pig 和 Hadoop 世界的新手。我遇到的问题可能很简单,但我无法继续。
所以我有下面的数据,基本上是一天的数据。 我需要计算员工一天花费的总小时数,即使用 PIG 的第一个上班时间(他到达办公室的时间)和最后一个下班时间(当天最后一次刷卡)之间的差异。
EmpID In_Time Out_Time
1 9:00 10:00
2 8:00 11:00
3 10:00 12:00
1 11:00 13:00
1 14:00 18:00
2 12:00 18:00
3 13:00 18:00
所以我写了下面的脚本,但它似乎没有给出正确的结果。
grunt> emprec = load '/emptime/emptime' using PigStorage() as (empid:int,in:chararray,out:chararray);
grunt> aggdata = group emprec by empid;
grunt> emptime = foreach aggdata generate (emprec.empid,MIN(emprec.in),MAX(emprec.out));
我写的脚本似乎没有得到正确的结果。
我需要的结果是
中间结果(我的理解)
EmpID In_Time Out_Time
1 9:00 18:00
2 8:00 18:00
3 10:00 18:00
所需的最终输出是 Out_Time-In_Time
的差异EmpID Total_Time
1 9:00
2 10:00
3 8:00
我写了最后一行来获取最小和最大时间,这样我就可以减去 2 并得到在办公室花费的总时间
请注意,如果您想将时间假定为 Int 或任何其他格式,请这样做,因为这只是一个示例。
提前致谢
此致, 车坛
在 chararray
数据类型上使用 MAX
、MIN
没有给您预期的结果。如果你想避免写 UDF
你可以按照这个解决方案:
我从数据开始:
1,9:00,10:00
2,8:00,11:00
3,10:00,12:00
1,11:00,13:00
1,14:00,18:00
2,12:00,18:00
3,13:00,18:00
emprec = load '/home/cloudera/pig.txt' using PigStorage(',') as (empid:int,in:chararray,out:chararray);
cleandata = foreach emprec generate [=11=] as ID ,(double)REPLACE(,':','.') as in_time,(double)REPLACE(,':','.') as out_time; --convert time to double so you can use eval functions on it
aggdata = group cleandata by ID;
emptime = foreach aggdata generate group ,MIN(cleandata.in_time),MAX(cleandata.out_time);
results = foreach emptime generate [=11=] as Emp_ID,REPLACE((chararray)( - ),'\.(?s)','\:0') as time_diff; --convert back to time
dump results;
输出:
(1,9:00)
(2,10:00)
(3,8:00)
如果您有兴趣创建 Pig UDF,那么这里是代码:
package Conversion;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
public class ConvertDot extends EvalFunc<String> {
@Override
public String exec(Tuple input) throws IOException {
String newstr = new String();
if(input == null || input.size() == 0)
return null;
try{
String str = (String)input.get(0);
if(str.contains(":"))
newstr = str.replace(':','.');
else if(str.contains("."))
newstr = str.replace('.',':');
else
newstr = str;
}catch (Exception e){
throw new IOException("Caught exception ", e);
}
return newstr;
}
}
$ cat ComputeTotalTime.pig
--Calculate Min, Man and Total time
REGISTER /home/hadoop/Desktop/Abhinav/ConvertDotColon.jar
emprec = LOAD '/home/hadoop/Desktop/Abhinav/swaptime.txt' USING PigStorage(',') AS (empid:int, in:chararray, out:chararray);
cleandata = FOREACH emprec GENERATE empid, (double)Conversion.ConvertDot(in) as in, (double)Conversion.ConvertDot(out) as out;
aggdata = group cleandata by empid;
emptime = foreach aggdata generate group, MIN(cleandata.in), MAX(cleandata.out);
results = foreach emptime generate [=10=] as EmpId, Conversion.ConvertDot((chararray)( - )) as Time_diff;
STORE results INTO '/home/hadoop/Desktop/Abhinav/TotalTime.txt';