Me gustaría duplicar los valores que están separados por |, transformándolos en nuevas columnas.

El siguiente archivo de ejemplo de subconjunto sería:

1_A 2_A 3_A
1|0 0|0 0|0
0|0 0|0 1|1
1|1 1|0 1|0
0|1 1|1 0|0
0|1 1|0 0|0
0|0 0|0 0|0
0|1 1|1 0|1
0|0 0|0 1|0
1|1 1|0 0|1
0|0 0|0 0|0

El formato deseado sería:

1_A 1_B 2_A 2_B 3_A 3_B
1|1 0|0 0|0 0|0 0|0 0|0
0|0 0|0 0|0 0|0 1|1 1|1
1|1 1|1 1|1 0|0 1|1 0|0
0|0 1|1 1|1 1|1 0|0 0|0
0|0 1|1 1|1 0|0 0|0 0|0
0|0 0|0 0|0 0|0 0|0 0|0
0|0 1|1 1|1 1|1 0|0 1|1
0|0 0|0 0|0 0|0 1|1 0|0
1|1 1|1 1|1 0|0 0|0 1|1
0|0 0|0 0|0 0|0 0|0 0|0

En el ejemplo anterior, la muestra 1_B son los valores duplicados a la derecha del carácter de tubería de la muestra 1_A.

Gracias por cualquier pista.

0
guidebortoli 11 oct. 2019 a las 17:30

4 respuestas

La mejor respuesta

¡awk al rescate!

$ awk 'NR==1 {for(i=1;i<=NF;i++) 
                {t=$i; 
                 sub("A","B",$i); 
                 printf "%s %s ",t,$i} 
              print ""; next}
             {for(i=1;i<=NF;i++) 
                {split($i,a,"|"); 
                 printf "%s %s ",a[1]"|"a[1],a[2]"|"a[2]} 
              print ""}' file

1_A 1_B 2_A 2_B 3_A 3_B
1|1 0|0 0|0 0|0 0|0 0|0 
0|0 0|0 0|0 0|0 1|1 1|1 
1|1 1|1 1|1 0|0 1|1 0|0 
0|0 1|1 1|1 1|1 0|0 0|0 
0|0 1|1 1|1 0|0 0|0 0|0 
0|0 0|0 0|0 0|0 0|0 0|0 
0|0 1|1 1|1 1|1 0|0 1|1 
0|0 0|0 0|0 0|0 1|1 0|0 
1|1 1|1 1|1 0|0 0|0 1|1 
0|0 0|0 0|0 0|0 0|0 0|0 
3
karakfa 11 oct. 2019 a las 16:00

Otra en awk:

$ awk '{
    for(i=1;i<=NF;i++)
        if(NR==1)
            sub(/A/,"& " i "_B",$i)
        else {
            t=$i
            sub(/\|/," ",t)
            sub(/\|/,"|"t"|",$i)
        }
}1' file

head -3 de salida:

1_A 1_B 2_A 2_B 3_A 3_B
1|1 0|0 0|0 0|0 0|0 0|0
0|0 0|0 0|0 0|0 1|1 1|1
...

Y uno en sed:

$ sed '1s/\(._\)A/\1A \1B/g; s/\([01]\)|\([01]\)/\1|\1 \2|\2/g' file

Salida:

1_A 1_B 2_A 2_B 3_A 3_B
1|1 0|0 0|0 0|0 0|0 0|0
0|0 0|0 0|0 0|0 1|1 1|1
...
3
James Brown 11 oct. 2019 a las 16:34

Esto debería funcionar:

def split_values(s):
    # split the string over '|', and format each to the expected output
    return [*map(lambda _: f"{_}|{_}", s.split('|'))]

# list of dataframes which we will later concat over
tmp_df_lst = []
for col in df.columns:
    # apply split_values over each column
    tmp_df = pd.DataFrame(df[col].apply(split_values).values.tolist(), 
                 columns=[f"{col[:-1]}A", f"{col[:-1]}B"])
    tmp_df_lst.append(tmp_df)

# result
pd.concat(tmp_df_lst, axis=1)

Salida:

    1_A 1_B 2_A 2_B 3_A 3_B
0   1|1 0|0 0|0 0|0 0|0 0|0
1   0|0 0|0 0|0 0|0 1|1 1|1
2   1|1 1|1 1|1 0|0 1|1 0|0
3   0|0 1|1 1|1 1|1 0|0 0|0
4   0|0 1|1 1|1 0|0 0|0 0|0
5   0|0 0|0 0|0 0|0 0|0 0|0
6   0|0 1|1 1|1 1|1 0|0 1|1
7   0|0 0|0 0|0 0|0 1|1 0|0
8   1|1 1|1 1|1 0|0 0|0 1|1
9   0|0 0|0 0|0 0|0 0|0 0|0
1
Andy 11 oct. 2019 a las 14:45

Por favor, intente seguir.

awk -F"[ |]" '
FNR==1{
  print $1,"1_B",$2,"2_B",$3,"3_B"
  next
}
FNR>1{
  for(i=1;i<=NF;i++){
     $i=$i "|" $i
  }
}
1
'  Input_file

Explicación : Agregando una explicación para el código anterior.

awk -F"[ |]" '                         ##Setting field separator eiter space or pipe here.
FNR==1{                                ##Checking condition if this is first line.
  print $1,"1_B",$2,"2_B",$3,"3_B"     ##Printing headers as per OP.
  next                                 ##Using next will skip all further statements from here.
}                                      ##Closing FNR==1 condition BLOCK here.
FNR>1{                                 ##Checking condition if FNR>1 then do following.
  for(i=1;i<=NF;i++){                  ##Starting a for loop from i=1 to till value of NF(number of fields in current line).
     $i=$i "|" $i                      ##Setting value of current field to current field |(pipe) current field value here.
  }                                    ##Closing BLOCK for for loop here.
}                                      ##Closing BLOCK for FNR>1 condition here.
1                                      ##Mentioning 1 will print edited/non-edited current line here.
'  Input_file                          ##Mentioning Input_file(which we need to process here).

La salida será la siguiente.

1_A 1_B 2_A 2_B 3_A 3_B
1|1 0|0 0|0 0|0 0|0 0|0
0|0 0|0 0|0 0|0 1|1 1|1
1|1 1|1 1|1 0|0 1|1 0|0
0|0 1|1 1|1 1|1 0|0 0|0
0|0 1|1 1|1 0|0 0|0 0|0
0|0 0|0 0|0 0|0 0|0 0|0
0|0 1|1 1|1 1|1 0|0 1|1
0|0 0|0 0|0 0|0 1|1 0|0
1|1 1|1 1|1 0|0 0|0 1|1
0|0 0|0 0|0 0|0 0|0 0|0
4
RavinderSingh13 11 oct. 2019 a las 14:52
58343428