2016-07-17 7 views
0

Ich habe eine Tabelle mit zwei Spalten (Code: chararray, sp: double)Spalte Aufteilung in Gruppen Schwein mit lateinischen

ich das zweite Feld sp in verschiedene Gruppen unterteilt werden soll (zB auf der Basis der Bedingung, wie (< 25), (> 25 < 45), (> = 45)

INPUT

code sp 
t001 60.0 
t001 75.0 
a003 34.0 
t001 60.0 
a003 23.0 
a003 23.0 
t001 45.0 
t001 10.0 
t001 8.0 
a003 20.0 
t001 38.0 
a003 55.0 
a003 50.0 
t001 08.0 
a003 44.0 

gewünschte Ausgabe.

code bin1  bin2  bin3 
     (<25) (>25 <45) >=45 
t001 3   1   4 
a003 3   2   2 

ich das Skript Ich versuche wie unten:

data = LOAD 'Sandy/rd.csv' using PigStorage(',') As (code:chararray,sp:double); 

data2 = DISTINCT data; 

selfiltnew = FOREACH data2 generate code, sp; 
group_new = GROUP selfiltnew by (code,sp); 

newselt = FOREACH group_new GENERATE selfiltnew.code AS code,selfiltnew.sp AS sp; 

bin1 = filter newselt by sp < 25.0; 
grp1 = FOREACH bin1 GENERATE newselt.code AS code, COUNT(newselt.sp) AS (sp1:double); 

bin2 = filter newselt by sp < 45 and sp >= 25; 
grp2 = FOREACH bin3 GENERATE newselt.code AS code, COUNT(newselt.sp) AS (sp2:double); 

bin3 = filter newselt by sp >=75; 
grp3 = FOREACH bin3 GENERATE newselt.code AS code, COUNT(newselt.sp) AS (sp3:double); 

newbin = JOIN grp1 by code,grp2 by code,grp3 by code; 

newtable = FOREACH newbin GENERATE grp1::group.code AS code, SUM(sp1) AS bin1,SUM(sp2) AS bin2,SUM(sp3) AS bin3; 

data2 = FOREACH newtable GENERATE code, bin1, bin2, bin3; 
dump newtable; 

Wie kann ich die richtige Ausgabe mit Schweinlatein bekommen?

+1

Bitte geben Sie an, was mit Ihrem Skript nicht stimmt, was erhalten Sie anstelle des erwarteten Ergebnisses – YakovL

+1

@YakovL - Fehler kommt an der grp1 = FOREACH bin1 GENERATE newselt.code AS-Code, COUNT (newselt.sp) AS (sp1: double) ; Hier möchte ich die Anzahl all jener sp berechnen, die unter 25 fallen. Ich erhalte den folgenden Fehler: Konnte die Übereinstimmungsfunktion für org.apache.pig.builtin.COUNT nicht ableiten, da mehrere oder keine von ihnen passen. Bitte verwenden Sie eine explizite Besetzung. – sandy

+0

Ich bin mir nicht sicher, ob diese Logik gut ist. Gibt es irgendwelche besten Lösungen, um in Behälter zu teilen? – sandy

Antwort

0

Ihren gewünschten Ausgang keine DISTINCT benötigt sehen. Außerdem müssen Sie einige der Schritte, die Sie verfolgen, nicht ausführen. Beachten Sie, dass, wenn die Quelle durch ein Leerzeichen getrennt wird Sie PigStorage(' ') statt PigStorage(',') Nach was @inquisitive_mind spitzen verwenden sollte, folgt der Code würde wie:

data = LOAD 'Sandy/rd.csv' using PigStorage(' ') As (code:chararray,sp:double); 
bin1 = filter data by sp < 25.0; 
grouped1 = GROUP bin1 by code; 
grp1 = FOREACH grouped1 GENERATE group AS code, COUNT(bin1.sp) AS (sp1:double); 
bin2 = filter data by (sp >= 25.0 AND sp<45); 
grouped2 = GROUP bin2 by code; 
grp2 = FOREACH grouped2 GENERATE group AS code, COUNT(bin2.sp) AS (sp2:double); 
bin3 = filter data by sp >= 45.0; 
grouped3 = GROUP bin3 by code; 
grp3 = FOREACH grouped3 GENERATE group AS code, COUNT(bin3.sp) AS (sp3:double); 
result= JOIN grp1 BY code, grp2 by code, grp3 by code; 
final_result = FOREACH result GENERATE grp1::code as code, grp1::sp1 as bin1, grp2::sp2 as bin2, grp3::sp3 as bin3; 

Hier ist der Ausgang:

enter image description here

+0

Danke für Ihre Antwort. Was ist mit Inner JOIN? Wenn eines von grp1, grp2 oder grp3 null itms hat, wird es am Ende null ergeben. Welche Join verwenden? In meinem tatsächlichen Datensatz habe ich fast sechs Grps und es gibt eine Möglichkeit von null Elementen in jeder der Gruppen. – sandy

0

Sie haben GROUP BY zu verwenden, bevor COUNT Verwendung

Quelle:COUNT
Usage
über die COUNT-Funktion die Anzahl der Elemente in einer Tasche zu berechnen. COUNT erfordert eine vorangehende GROUP ALL-Anweisung für globale Zählungen und eine GROUP BY-Anweisung für Gruppenzählungen.

bin1 = filter newselt by sp < 25.0; 
grouped1 = GROUP bin1 by (newselt.code); 
grp1 = FOREACH grouped1 GENERATE group AS code, COUNT(newselt.sp) AS (sp1:double); 
+0

Danke für Ihre Antwort. – sandy