2012-05-15 22 views
5

Mi conjunto de datos tiene el siguiente aspecto:Aplanar tupla como una bolsa

(A, (1,2)) 
(B, (2,9)) 

me gustaría "aplanar" las tuplas de cerdo, básicamente repitiendo cada registro para cada valor que se encuentra en el centro de la tupla, de tal manera que el resultado esperado es:

(A, 1) 
(A, 2) 
(B, 2) 
(B, 9) 

sé que esto es posible cuando las tuplas (1,2) y (2,9) son bolsas en su lugar.

Respuesta

9

Su visión es buena; es posible transformando la tupla en una bolsa. El esquema queremos aspirar es: {a: chararray, {(chararray)}}, por ejemplo: (A, {(1), (2)})

Aquí está la solución a su problema:

A = LOAD 'data.txt' AS (a:chararray,b:(b1:chararray,b2:chararray)); 
B = FOREACH A GENERATE a, TOBAG(b.b1,b.b2); 
C = FOREACH B GENERATE a, FLATTEN($1); 

La parte mágica es el operador TOBAG.

+3

¡Guau! En este caso, la tupla tiene dos elementos (b.b1, b.b2). ¿Cómo hago esto cuando el tamaño de la tupla puede variar? – Marquez

+0

También me gustaría saber cómo hacer esto con una Tuple de longitud variable. –

+0

Puede escribir su propia UDF para ese fin. 'DataBag bag = BagFactory.getInstance(). NewDefaultBag(); for (int i = 0; i hobgoblin

0

Sé que este es un hilo viejo, pero no pude conseguir el método anterior para que funcione. Pensé que compartiré mis hallazgos.

input: (1-2-3, abc) 
     (4-5-6, xyz) 
desired output: 
     (1, abc) 
     (2, abc) 
     (3, abc) 
     (4, xyz) 
     (5, xyz) 
     (6, xyz) 

Inicialmente, solía STRSPLIT que genera una tupla resultante en la entrada similar a la anterior pero no tuvo éxito.

output = FOREACH input GENERATE FLATTEN(TOBAG(STRSPLIT($0, '-'))), $1 

Esto dio lugar a la salida como:

(1,2,3,abc) 
(4,5,6,xyz) 

Sin embargo, cuando solía tokenize y reemplazar las funciones que me dieron el resultado deseado.

output = FOREACH input GENERATE FLATTEN(TOKENIZE(REPLACE($0,'-', ' '))), $1;