Python: cómo extraer una cadena de un archivo de texto para usarla como datos

esta es la primera vez que escribo un script de python y tengo algunos problemas para comenzar. Digamos que tengo un archivo txt llamado Test.txt que contiene esta información.

                                   x          y          z      Type of atom
ATOM   1     C1  GLN D  10      26.395      3.904      4.923    C
ATOM   2     O1  GLN D  10      26.431      2.638      5.002    O
ATOM   3     O2  GLN D  10      26.085      4.471      3.796    O 
ATOM   4     C2  GLN D  10      26.642      4.743      6.148    C  

Lo que quiero hacer es eventualmente escribir un script que encuentre el centro de masa de estos tres átomos. Básicamente, quiero resumir todos los valores de x en ese archivo txt con cada número multiplicado por un valor dado según el tipo de átomo.

Sé que necesito definir las posiciones para cada valor de x, pero tengo problemas para descubrir cómo hacer que estos valores de x se representen como números en lugar de txt de una cadena. Debo tener en cuenta que necesitaré multiplicar estos números por el tipo de átomo, así que necesito una forma de mantenerlos definidos para cada tipo de átomo. ¿Alguien puede empujarme en la dirección correcta?

preguntado el 27 de julio de 12 a las 16:07

En primer lugar, ¿es esto una tarea? -

¡Bienvenido a SO! ¿Puedes mostrarnos el código que tienes hasta ahora? Si tiene código para leer el archivo y obtener el x valores como cadenas, ¡es un gran comienzo! Básicamente, si nos muestra lo que tiene, podemos ayudarlo a mejorarlo y llevarlo a un punto en el que pueda usarlo. -

¿Esto sale de su software como un archivo separado por tabulaciones? Si es así, podrías consultar docs.python.org/library/csv.html -

Además, 3 átomos? Según mi cuenta, son 4 ;-) -

No es tarea. Estoy haciendo mi propia investigación sobre algún resultado de otro programa que he automatizado usando bash. Eventualmente tendré que aprender Python en el futuro, así que pensé que tratar de automatizar esta tarea sería un buen comienzo y me ahorraría mucho tiempo. -

3 Respuestas

mass_dictionary = {'C':12.0107,
                   'O':15.999
                   #Others...?
                  }

# If your files are this structured, you can just
# hardcode some column assumptions.
coords_idxs = [6,7,8]
type_idx = 9

# Open file, get lines, close file.
# Probably prudent to add try-except here for bad file names.
f_open = open("Test.txt",'r')
lines = f_open.readlines()
f_open.close()

# Initialize an array to hold needed intermediate data.
output_coms = []; total_mass = 0.0;

# Loop through the lines of the file.
for line in lines:

    # Split the line on white space.
    line_stuff = line.split()

    # If the line is empty or fails to start with 'ATOM', skip it.
    if (not line_stuff) or (not line_stuff[0]=='ATOM'):
        pass

    # Otherwise, append the mass-weighted coordinates to a list and increment total mass.
    else:
        output_coms.append([mass_dictionary[line_stuff[type_idx]]*float(line_stuff[i]) for i in coords_idxs])
        total_mass = total_mass + mass_dictionary[line_stuff[type_idx]]

# After getting all the data, finish off the averages.
avg_x, avg_y, avg_z = tuple(map( lambda x: (1.0/total_mass)*sum(x), [[elem[i] for elem in output_coms] for i in [0,1,2]]))


# A lot of this will be better with NumPy arrays if you'll be using this often or on
# larger files. Python Pandas might be an even better option if you want to just
# store the file data and play with it in Python.

Respondido 27 Jul 12, 17:07

line_stuff = line.replace("\n","").split() -- Esto es equivalente a line_stuff.split(). - mgilson

A menudo me sale "\n" al final de mis cosas cuando solo uso split(). Creo que depende del formato de la línea si esto funciona o no, siempre me ha parecido prudente incluirlo. - Ely

¿Está utilizando split(' ')? Eso podría dar saltos de línea finales ... pero no split() - mgilson

Tienes razón sobre split(); los casos de los que estaba generalizando eran con un reg-ex usando cadenas, como re.split(re.compile(' {2,}'), some_str) así que me acostumbré a usar el reemplazo para cosas como \r y \n pero no es necesario aquí en absoluto. Editado. - Ely

Básicamente usando el habiertos función en python puede abrir cualquier archivo. Entonces, puede hacer algo de la siguiente manera: --- el siguiente fragmento no es una solución para todo el problema, sino un enfoque.

def read_file():
    f = open("filename", 'r')
    for line in f:
        line_list = line.split()
        ....
        ....
    f.close()

A partir de este momento, tiene una buena configuración de lo que puede hacer con estos valores. Básicamente, la segunda línea solo abre el archivo para leerlo. La tercera línea define un bucle for que lee el archivo una línea a la vez y cada línea va al line variable.

La última línea de ese fragmento básicamente divide la cadena, en cada espacio en blanco, en una lista. Entonces line_list[0] será el valor en su primera columna y así sucesivamente. Desde este punto, si tiene alguna experiencia en programación, puede usar declaraciones if y demás para obtener la lógica que desea.

** También tenga en cuenta que el tipo de valores almacenados en esa lista será una cadena, por lo que si desea realizar operaciones aritméticas, como sumar, debe tener cuidado.

* Editado para corrección de sintaxis.

Respondido 27 Jul 12, 16:07

Deberías usar el término list en lugar de array. Además, nunca llamas f.close() (Tenga en cuenta que este tipo de cosas es exactamente lo que el with declaración fue diseñada para manejar más fácil). - mgilson

No soy fan de with pero usted debe estar familiarizado con él. Sin embargo, el consejo de nunca usar file.close() es malo.. muchas veces es mejor manejarlo así. - Ely

@EMS: @mgilson no quiso decir "nunca debes usar file.close()", quiso decir "no llamaste f.close() y deberías tener (y si with hubiera sido utilizado, este error no hubiera ocurrido)". - DSM

Si tiene pandas instalado, echa un vistazo a la read_fwf función que importa un archivo de ancho fijo y crea un DataFrame (estructura de datos tabulares 2-d). Le ahorrará líneas de código en la importación y también le brindará una gran cantidad de funciones de manipulación de datos si desea realizar manipulaciones de datos adicionales.

Respondido 28 Jul 12, 05:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.