2010-04-21 7 views
5

Je suis assez nouveau à la programmation Python et apprécierait un peu d'aide à un problème que j'ai ...python: trouver et remplacer les numéros <1 dans le fichier texte

Fondamentalement, j'ai plusieurs fichiers texte qui contiennent des valeurs de vitesse comme tel:

0.259515E + 03 + 03 0.235095E 0.208262E + 03 + 03 0.230223E 0.267333E + 03 + 03 0.217889E 0.156233E + 03 + 03 0.144876E 0.136187E + 03 + 00 0.137865E

etc pour beaucoup de lignes ...

Ce que je dois faire est de convertir toutes les valeurs dans le fichier texte qui sont moins de 1 (par ex. 0.137865E + 00 ci-dessus) à une valeur arbitraire de 0.100000E + 01. Bien qu'il semble assez simple de remplacer des valeurs spécifiques par la méthode 'replace()' et une boucle while, comment faites-vous cela si vous voulez remplacer une plage?

grâce

Répondre

7

Je pense que lorsque vous commencez la programmation, c'est utile de voir quelques exemples; et je suppose que vous avez d'abord essayé ce problème!

Voici une cassure de la façon dont vous pouvez aborder ceci:

contents='0.259515E+03 0.235095E+03 0.208262E+03 0.230223E+03 0.267333E+03 0.217889E+03 0.156233E+03 0.144876E+03 0.136187E+03 0.137865E+00' 

Les split method travaux sur cordes. Il renvoie une liste de chaînes. Par défaut, il se divise sur les espaces:

string_numbers=contents.split() 
print(string_numbers) 
# ['0.259515E+03', '0.235095E+03', '0.208262E+03', '0.230223E+03', '0.267333E+03', '0.217889E+03', '0.156233E+03', '0.144876E+03', '0.136187E+03', '0.137865E+00'] 

Le map command applique son premier argument (la fonction float) à chacun des éléments de son second argument (la liste string_numbers). La fonction float convertit chaque chaîne en un objet à virgule flottante.

float_numbers=map(float,string_numbers) 
print(float_numbers) 
# [259.51499999999999, 235.095, 208.262, 230.22300000000001, 267.33300000000003, 217.88900000000001, 156.233, 144.876, 136.18700000000001, 0.13786499999999999] 

Vous pouvez utiliser un list comprehension pour traiter la liste, la conversion des nombres inférieurs à 1 dans le numéro 1. Le conditional expression(1 if num<1 else num) est égal à 1 lorsque num est inférieur à 1, sinon, il est égal à num.

processed_numbers=[(1 if num<1 else num) for num in float_numbers] 
print(processed_numbers) 
# [259.51499999999999, 235.095, 208.262, 230.22300000000001, 267.33300000000003, 217.88900000000001, 156.233, 144.876, 136.18700000000001, 1] 

Ceci est la même chose, en une seule ligne:

processed_numbers=[(1 if num<1 else num) for num in map(float,contents.split())] 

Pour générer une chaîne à partir des éléments de processed_numbers, vous pouvez utiliser le str.join method:

comma_separated_string=', '.join(map(str,processed_numbers)) 
# '259.515, 235.095, 208.262, 230.223, 267.333, 217.889, 156.233, 144.876, 136.187, 1' 
+0

c'est génial. J'ai passé des âges aujourd'hui se demandant pourquoi l'expression conditionnelle ne fonctionnait pas, alors réalisé que je devais mettre à niveau de 2.4 – hjp

4

technique typique serait:

  • lecture fichier ligne par ligne
  • split chaque ligne dans une liste de chaînes
  • convertir chaque chaîne au flotteur
  • comparer converti valeur avec 1
  • remplacer en cas de besoin
  • Réécrire vers le nouveau fichier

comme moi, je l'espère vois pas que vous ayez encore un code que ce serait un bon départ

+0

merci, je savais qu'ils devraient être convertis en chars, mais ne savaient pas les lignes de séparation. – hjp

3
def float_filter(input): 
    for number in input.split(): 
     if float(number) < 1.0: 
      yield "0.100000E+01" 
     else: 
      yield number 

input = "0.259515E+03 0.235095E+03 0.208262E+03 0.230223E+03 0.267333E+03 0.217889E+03 0.156233E+03 0.144876E+03 0.136187E+03 0.137865E+00" 
print " ".join(float_filter(input)) 
0

Vous pourrait utiliser des expressions régulières pour analyser la chaîne. Je suppose ici que la mantisse n'est jamais plus grande que 1 (c'est-à-dire commence par 0). Cela signifie que pour que le nombre soit inférieur à 1, l'exposant doit être 0 ou négatif. L'expression régulière suivante correspond à "0", ".", Au nombre illimité de chiffres décimaux (au moins 1), à "E" et à "+00" ou "-" et à deux chiffres décimaux.

0\.\d+E(-\d\d|\+00) 

En supposant que vous avez le fichier lu dans « texte » variable, vous pouvez utiliser l'expression régulière avec le code python suivant:

result = re.sub(r"0\.\d*E(-\d\d|\+00)", "0.100000E+01", text) 

Edit: viens juste de réaliser que la description ne limite pas la plage valide des nombres d'entrée aux nombres positifs. Les nombres négatifs peuvent être jumelés à l'expression rationnelle suivante:

-0\.\d+E[-+]\d\d 

Cela peut être en alternance avec le premier en utilisant le (motif1 | pattern2) syntaxe qui se traduit par le code Python suivant:

result = re.sub(r"(0\.\d+E(-\d\d|\+00)|-0\.\d+E[-+]\d\d)", "0.100000E+00", subject) 

Aussi, si il y a une chance que l'exposant dépasse 99, l'expression rationnelle peut être modifiée en ajoutant un signe '+' après les motifs '\ d \ d'. Cela permet aux chiffres correspondants se terminant par deux chiffres OU PLUS.

0

J'ai le script qui fonctionne comme je veux maintenant ... merci les gens. Lors de l'écriture de la liste dans un nouveau fichier, j'ai utilisé la méthode de remplacement pour me débarrasser des crochets et des virgules - y a-t-il un moyen plus simple?

ftext = open("C:\\Users\\hhp06\\Desktop\\out.grd", "r") 
otext = open("C:\\Users\\hhp06\\Desktop\\out2.grd", "w+") 

for line in ftext: 
    stringnum = line.split() 
    floatnum = map(float, stringnum) 
    procnum = [(1.0 if num<1 else num) for num in floatnum] 
    stringproc = str(procnum) 
    s = (stringproc).replace(",", " ").replace("[", " ").replace("]", "") 
    otext.writelines(s + "\n") 
otext.close() 
+0

Hi hjp. Il est préférable d'ajouter un commentaire pour poser une question directement à une personne ou pour poster une nouvelle question. De cette façon, plus de gens le remarqueront. Mais, pour répondre à votre question, vous ne voulez certainement pas utiliser 'replace' pour cette tâche. Essayez 's = ',' .join (map (str, procnum))'. Voir http://docs.python.org/library/stdtypes.html#str.join – unutbu

3
import numpy as np 

a = np.genfromtxt('file.txt') # read file 
a[a<1] = 0.1     # replace 
np.savetxt('converted.txt', a) # save to file 
Questions connexes