• Publicidad

Sacar nombres de especies sin repetición

Perl aplicado a la bioinformática

Re: Sacar nombres de especies sin repetición

Notapor explorer » 2011-01-26 17:20 @764

No, no hay ningún tipo de ahorro, ni de CPU (los pasos son los mismos) ni de espacio en disco (la ocupación de bloques de disco será casi siempre la misma.

Pero aún así, es posible realizar esta operación con menos pasos: se puede eliminar completamente la línea 15 e incluir su funcionalidad dentro del bucle.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Publicidad

Re: Sacar nombres de especies sin repetición

Notapor wanako » 2011-01-26 21:26 @934

Ahora entiendo la idea :)

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my %especies;
  7. my $archivo = 'fila.txt';
  8.  
  9. open DATOS, $archivo or die "$!\n";
  10.  
  11. while (<DATOS>) {
  12.         if ( /^>\w+\s+(.+)/ and ! $especies{$1} ) {
  13.         $especies{$1} = 1;
  14.         print "$1\n";
  15.     }
  16. }
  17.  
  18. close DATOS;
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
wanako
Perlero nuevo
Perlero nuevo
 
Mensajes: 27
Registrado: 2010-09-23 11:27 @519

Re: Sacar nombres de especies sin repetición

Notapor explorer » 2011-01-27 16:26 @727

También así :)

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my %visto;
  2.  
  3. open my $fh, q[<], 'kk.txt';
  4.  
  5. while (<$fh>) {
  6.         /^>\w+\s+(.+)/  # si capturamos el nombre
  7.     and ! $visto{$1}++  # y si no ha sido visto antes, contamos una visita y seguimos
  8.     and print "$1\n"    # entonces imprimimos el nombre
  9.     ;
  10. }
  11.  
  12. close   $fh;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Lo malo es que así no salen los nombres ordenados de forma alfabética, sino según en el orden en que aparecen en el fichero.

Con las nuevas expresiones regulares, se puede hacer un poco más expresivo
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while (<$fh>) {
  2.           /^>\w+\s+(?<nombre>.+)/       # si capturamos el nombre
  3.     and not $visto{$+{nombre}}++        # y si no ha sido visto antes, contamos una visita y seguimos
  4.     and     print "$+{nombre}\n"        # entonces imprimimos el nombre
  5.     ;
  6. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Sacar nombres de especies sin repetición

Notapor wanako » 2011-01-27 23:28 @019

Con el autoincremento no vale, ¡Trampa trampa! 8)
Al principio no era jugar con los valores sino con las llaves, pero me gusta porque es más rápido:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use Time::HiRes;
  4. use Benchmark qw(:all);
  5. use Benchmark qw(:hireswallclock);
  6.  
  7. my $bench = timethese( -10, {
  8.     t_explorer => sub{\&t_e},
  9.     t_wanako => sub{\&t_w},
  10. } );
  11. cmpthese $bench;
  12.  
  13. sub t_e {
  14.     my %e;
  15.     while (<DATA>) {
  16.         /^>\w+\s+(?<nombre>.+)/
  17.         and not $e{$+{nombre}}++
  18.         and print "$+{nombre}\n";
  19.     }
  20. }
  21.  
  22. sub t_w {
  23.     my %w;
  24.     while (<DATA>) {
  25.         if ( /^>\w+\s+(.+)/ and ! $w{$1} ) {
  26.             $w{$1} = 1;
  27.             print "$1\n";
  28.         }
  29.     }
  30. }
  31.  
  32. __DATA__
  33. >TPC2_XENLA Xenopus laevis
  34. ATGGAGTCGGAGCCGCTGCTCGGTTGGAGCGTCAATCTGCCT
  35. >TPC2_XENTR Xenopus tropicalis
  36. AAGTGACCGTAGACCAAAGCGAGTTTCGGCTCCAGGGAAGCG
  37. >TPC2_XENLA Xenopus laevis
  38. ATGGAGTCGGAGCCGCTGCTCGGTTGGAGCGTCAATCTGCCT
  39. >TPC2_XENTR Explorer tropicalis
  40. AAGTGACCGTAGACCAAAGCGAGTTTCGGCTCCAGGGAAGCG
  41. >TPC2_XENLA Wanako laevis
  42. ATGGAGTCGGAGCCGCTGCTCGGTTGGAGCGTCAATCTGCCT
  43. >TPC2_XENTR Xenopus tropicalis
  44. AAGTGACCGTAGACCAAAGCGAGTTTCGGCTCCAGGGAAGCG
  45.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Salida:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Benchmark: running t_explorer, t_wanako for at least 10 CPU seconds...
t_explorer: 10.095 wallclock secs (10.09 usr +  0.00 sys = 10.09 CPU) @ 6930561.92/s (n=69957092)
  t_wanako: 10.0298 wallclock secs (10.03 usr +  0.00 sys = 10.03 CPU) @ 7084578.71/s (n=71065409)
                Rate t_explorer   t_wanako
t_explorer 6930562/s         --        -2%
t_wanako   7084579/s         2%         --
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
wanako
Perlero nuevo
Perlero nuevo
 
Mensajes: 27
Registrado: 2010-09-23 11:27 @519

Re: Sacar nombres de especies sin repetición

Notapor explorer » 2011-01-28 10:21 @473

¿No deberías colocar un

seek DATA, 0, 0;

al principio de cada subrutina? Sin esa línea, la lectura de de DATA se agota en la primera ejecución del primer while().

Colocando un par de líneas seek() delante de los while(), -y ajustando el benchmark a 1 s-, me sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Benchmark: running t_explorer, t_wanako for at least 1 CPU seconds...
t_explorer: 1.53997 wallclock secs ( 1.05 usr + -0.00 sys =  1.05 CPU) @ 5242879.05/s (n=5505023)
  t_wanako: 1.90747 wallclock secs ( 1.04 usr +  0.01 sys =  1.05 CPU) @ 4918272.38/s (n=5164186)
                Rate   t_wanako t_explorer
t_wanako   4918272/s         --        -6%
t_explorer 5242879/s         7%         --
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


De todas maneras, y como te dije, el número de operaciones es el mismo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
explorer@casa:~/Documentos/Desarrollo> perl -MO=Concise ./code_24373.pl
24 <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 code_24373.pl:3) v:{ ->3
6     <@> seek vK/3 ->7
-        <0> ex-pushmark s ->3
3        <#> gv[*DATA] s ->4
4        <$> const[IV 0] s ->5
5        <$> const[IV 0] s ->6
7     <;> nextstate(main 1 code_24373.pl:4) v:{ ->8
8     <0> padhv[%e:1,16] vM/LVINTRO ->9
9     <;> nextstate(main 10 code_24373.pl:5) v:{ ->a
11    <2> leaveloop vK/2 ->12
a        <{> enterloop(next->v last->11 redo->b) v ->w
-        <1> null vK/1 ->11
10          <|> and(other->b) vK/1 ->11
z              <1> defined sK/1 ->10
-                 <1> null sK/2 ->z
-                    <1> ex-rv2sv sKRM*/1 ->x
w                       <#> gvsv[*_] s ->x
y                    <1> readline[t5] sKS/1 ->z
x                       <#> gv[*DATA] s ->y
-              <@> lineseq vKP ->-
b                 <;> nextstate(main 9 code_24373.pl:6) v:{ ->c
-                 <1> null vK/1 ->v
m                    <|> and(other->n) vK/1 ->v
-                       <1> null sK/1 ->m
d                          <|> and(other->e) sK/1 ->m
c                             </> match(/"^>\\w+\\s+(?<nombre>.+)"/) s/RTIME ->d
l                             <1> not sK/1 ->m
k                                <1> postinc[t7] sK/1 ->l
j                                   <2> helem sKRM/2 ->k
e                                      <0> padhv[%e:1,16] sR ->f
i                                      <2> helem sK/2 ->j
g                                         <1> rv2hv sKR/1 ->h
f                                            <#> gv[*+] s ->g
h                                         <$> const[PV "nombre"] s/BARE ->i
u                       <@> print vK ->v
n                          <0> pushmark s ->o
-                          <1> ex-stringify sK/1 ->u
-                             <0> ex-pushmark s ->o
t                             <2> concat[t9] sK/2 ->u
r                                <2> helem sK/2 ->s
p                                   <1> rv2hv sKR/1 ->q
o                                      <#> gv[*+] s ->p
q                                   <$> const[PV "nombre"] s/BARE ->r
s                                <$> const[PV "\n"] s ->t
v                 <0> unstack v ->w
12    <;> nextstate(main 11 code_24373.pl:11) v:{ ->13
16    <@> seek vK/3 ->17
-        <0> ex-pushmark s ->13
13       <#> gv[*DATA] s ->14
14       <$> const[IV 0] s ->15
15       <$> const[IV 0] s ->16
17    <;> nextstate(main 11 code_24373.pl:12) v:{ ->18
18    <0> padhv[%w:11,16] vM/LVINTRO ->19
19    <;> nextstate(main 15 code_24373.pl:13) v:{ ->1a
23    <2> leaveloop vK/2 ->24
1a       <{> enterloop(next->1x last->23 redo->1b) v ->1y
-        <1> null vK/1 ->23
22          <|> and(other->1b) vK/1 ->23
21             <1> defined sK/1 ->22
-                 <1> null sK/2 ->21
-                    <1> ex-rv2sv sKRM*/1 ->1z
1y                      <#> gvsv[*_] s ->1z
20                   <1> readline[t16] sKS/1 ->21
1z                      <#> gv[*DATA] s ->20
-              <@> lineseq vKP ->-
1b                <;> nextstate(main 14 code_24373.pl:14) v:{ ->1c
-                 <1> null vKP/1 ->1x
1i                   <|> and(other->1j) vK/1 ->1x
-                       <1> null sK/1 ->1i
1d                         <|> and(other->1e) sK/1 ->1i
1c                            </> match(/"^>\\w+\\s+(.+)"/) s/RTIME ->1d
1h                            <1> not sK/1 ->1i
1g                               <2> helem sK/2 ->1h
1e                                  <0> padhv[%w:11,16] sR ->1f
-                                   <1> ex-rv2sv sK/1 ->1g
1f                                     <#> gvsv[*1] s ->1g
1w                      <@> leave vKP ->1x
1j                         <0> enter v ->1k
1k                         <;> nextstate(main 12 code_24373.pl:15) v ->1l
1p                         <2> sassign vKS/2 ->1q
1l                            <$> const[IV 1] s ->1m
1o                            <2> helem sKRM*/2 ->1p
1m                               <0> padhv[%w:11,16] sR ->1n
-                                <1> ex-rv2sv sK/1 ->1o
1n                                  <#> gvsv[*1] s ->1o
1q                         <;> nextstate(main 12 code_24373.pl:16) v ->1r
1v                         <@> print vK ->1w
1r                            <0> pushmark s ->1s
-                             <1> ex-stringify sK/1 ->1v
-                                <0> ex-pushmark s ->1s
1u                               <2> concat[t20] sK/2 ->1v
-                                   <1> ex-rv2sv sK/1 ->1t
1s                                     <#> gvsv[*1] s ->1t
1t                                  <$> const[PV "\n"] s ->1u
1x                <0> unstack v ->1y
./code_24373.pl syntax OK
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Se observa que las operaciones que hay dentro de las subrutinas son casi las mismas
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Sacar nombres de especies sin repetición

Notapor wanako » 2011-01-31 18:34 @815

¡Gracias por la corrección!

El ejercicio ha sido más útil para mí que para el creador del hilo, parece :mrgreen:
wanako
Perlero nuevo
Perlero nuevo
 
Mensajes: 27
Registrado: 2010-09-23 11:27 @519

Re: Sacar nombres de especies sin repetición

Notapor explorer » 2011-01-31 19:40 @861

Aún no sabemos si le sirvió tu solución...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Anterior

Volver a Bioinformática

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados