如何在猪拉丁语脚本中没有前导零时将值转换为 hhmm 格式

Posted

技术标签:

【中文标题】如何在猪拉丁语脚本中没有前导零时将值转换为 hhmm 格式【英文标题】:how to convert a value to hhmm format when it has no leading zeros in pig latin script 【发布时间】:2017-03-12 16:56:57 【问题描述】:

我试图找出猪关系中两个不同时间场之间的差异。我可以使用猪的 todate() 方法,但它应该是 hhmm 格式。但是它没有前导零。例如,如果这两个字段的值分别为 1245 和 1425,我可以找到使用 todate 转换它们的差异。但是,如果值是 945 和 823,那么我无法使用 todate 进行转换,因为没有前导零。

但是我写了一个 python udf 试图左填充一个零。请在下面找到代码

 @outputSchema("time:bytearray")


def zero(time):
        time = str(time)
        if len(time)<= 3:
                return '0'+ time
        else:
                return time

第一步:注册我的python函数

REGISTER '/home/Jig13517/zeropad.py' using jython AS myfuncs ;

请在下面找到关系

Airlines_data_schema = LOAD '/user/Jig13517/pigsample/Airlines_data.csv' USING PigStorage('\t') AS (Year,Month,DayofMonth,DayofWeek,DepTime_actual,CRSDeptime,Arrtime_actual,CRSArrtime,UniqueCarrier,FlightNum,TailNum_Plane,ActualElapsedTime,CRSElapsedTime,Airtime,Arrdelay,Depdelay,Origin,Dest,Distance,Taxiin,Taxiout,Cancelled,CancellationCode,Diverted,CarrierDelay,WeatherDelay,NASDelay,SecurityDelay,LateAircraftDelay);

======================================

然后我尝试用零填充列值

airlines_new = FOREACH Airlines_data_schema GENERATE Year,Month,DayofMonth,DayofWeek,myfuncs.zero($4) AS DepTime_actual_new,myfuncs.zero($5) AS CRSDeptime_new,myfuncs.zero($6) AS Arrtime_actual_new,myfuncs.zero($7) AS CRSArrtime_new,UniqueCarrier,FlightNum,TailNum_Plane,ActualElapsedTime,CRSElapsedTime,Airtime,Arrdelay,Depdelay,Origin,Dest,Distance,Taxiin,Taxiout,Cancelled,CancellationCode,Diverted,CarrierDelay,WeatherDelay,NASDelay,SecurityDelay,LateAircraftDelay ;

=================================

应用python udf后的样本数据

 (2008,1,3,4,617,615,652,650,WN,11,N689SW,95,95,70,2,2,IND,MCI,451,6,19,0,,0,NA,NA,NA,NA,NA,,,,None,None,None,None,,,,,,,,,,,,,,,,,,,,,)

但是我们可以在上面看到它没有转换列值。我得到相同的字段不变。请让我知道我的 udf 出了什么问题,或者有什么猪方法可以完成这项任务。

【问题讨论】:

请在您的输入中添加minimal reproducible example。我们不需要查看所有 30+ 列的问题 【参考方案1】:

str.zfill 函数可以提供帮助

输入.txt

1245
1425
945
823

pig_udfs.py

@outputSchema('time:chararray')
def lpad_time(time):
    return time.zfill(4)

time_formatter.pig

register pig_udfs.py using jython as myfuncs;
A = LOAD 'input.txt' USING PigStorage();
B = FOREACH A GENERATE myfuncs.lpad_time((chararray) $0);
\d B

输出

(1245)
(1425)
(0945)
(0823)

显然,您可以让 Python 自己完成整个 todate 函数...

另外,如果分钟数为零,我不清楚你的问题。


编辑

airlines.csv

2008,1,3,4,617,615,652,650,WN,11,N689SW,95,95,70,2,2,IND,MCI,451,6,19,0,,0,NA,NA,NA,NA,NA,,,,None,None,None,None,,,,,,,,,,,,,,,,,,,,,

猪码

register pig_udfs.py using jython as myfuncs;
A = LOAD 'airlines.csv' USING PigStorage(',');
B = FOREACH A GENERATE $0 AS Year, $1 AS Month, $2 AS DayofMonth, $4 AS DayofWeek,myfuncs.lpad_time((chararray) $4) AS DepTime_actual_new,myfuncs.lpad_time((chararray) $5) AS CRSDeptime_new,myfuncs.lpad_time((chararray) $6) AS Arrtime_actual_new,myfuncs.lpad_time((chararray) $7) AS CRSArrtime_new,$8 AS UniqueCarrier,$9 AS FlightNum,$10 AS TailNum_Plane,$11 AS ActualElapsedTime, $12 AS CRSElapsedTime, $13 AS Airtime, $14 AS Arrdelay, $15 AS Depdelay, $16 AS Origin, $17 AS Dest, $18 AS Distance, $19 AS Taxiin, $20 AS Taxiout, $21 AS Cancelled, $22 AS CancellationCode, $23 AS Diverted, $24 AS CarrierDelay, $25 AS WeatherDelay, $26 AS NASDelay, $27 AS SecurityDelay, $28 AS LateAircraftDelay ;
\d B

输出

(2008,1,3,617,0617,0615,0652,0650,WN,11,N689SW,95,95,70,2,2,IND,MCI,451,6,19,0,,0,NA,NA,NA,NA,NA)

【讨论】:

分钟没有被零填充,我的目的是让它们都统一(即)。如果提交的文件有 1245,那么如果它的 845 就可以了,然后将其设为 0845。逻辑是,如果它有 4 位数字,则保持原样。如果是三位数,则左填充一个零。 这不是我的回答吗?但真的,分钟没有填充?你应该如何区分01:0900:19 好吧我的错误可能我不清楚。我希望格式为 hhmm,其中 945 理想情况下应该是 0945。是的,应该填充小时而不是分钟。我仍然面临同样的问题。它没有被转换。如果您看到第 4、第 5、第 6 和第 7 列,它仍然没有被填充。 (2008,1,3,4,628,620,804,750,WN,448,N428WN,96,90,76,14,8,IND,BWI,515,3,17,0,,0,NA,NA,NA,NA,NA, ,,,无,无,无,无,,,,,,,,,,,,,,,,,,,,,) 你在看我的回答吗?值显然是填充的......我不知道你做错了什么,对不起 我让它工作了,它正在传递归档的值,但它实际上并没有改变它的值,它改变了像这样的值:(2008,1,3,4,array('b', [54, 49, 55]),array('b', [54, 49, 53]),array('b', [54, 53, 50]),array('b', [54, 53, 48]) ,WN,11,N689SW,95,95,70,2,2,IND,MCI,451,6,19,0,,0,NA,NA,NA,NA,NA) 代替 ('b', [54, 49, 55]) 我们应该得到 0617 只是想知道它为什么将其转换为数组。【参考方案2】:

嘿@cricket_007 我让它工作了。我将列字段作为字节数组传递,这是我正在做的错误。然后,当我将架构更改为 chararray 时,它开始填充零。非常感谢。 请在下面找到更正的记录:

(2008,1,3,4,0617,0615,0652,0650,WN,11,N689SW,95,95,70,2,2,IND,MCI,451,6,19,0,,0,NA,NA,NA,NA,NA)
(2008,1,3,4,0628,0620,0804,0750,WN,448,N428WN,96,90,76,14,8,IND,BWI,515,3,17,0,,0,NA,NA,NA,NA,NA)

【讨论】:

以上是关于如何在猪拉丁语脚本中没有前导零时将值转换为 hhmm 格式的主要内容,如果未能解决你的问题,请参考以下文章

如何在猪拉丁语的日期时间范围内创建缺失的记录

如何在我的猪脚本中设置多行字符串?

谷歌表格脚本将值转换为小写

如何在猪脚本中对单行中的字段进行总计?

尝试在猪中加载文件,但每次都会出现此问题。警告 IMPLICIT_CAST_TO_FLOAT 2 次

如何将值与前导零或一般对齐?