У меня есть этот код:
#! /usr/bin/env python
import sys
import numpy
import math
inputfile = open(sys.argv[1], 'r')
atoms = numpy.zeros((6, 3), dtype='float64')
for line in inputfile:
sline = line.split()
header = sline[0]
for i in range(1, 4, 1):
atoms[i] = float(sline[i])
# print(float(sline[i]))
print(atoms)
Содержимое входного файла:
O5 -2.978 -1.342 0.528
C1 -4.475 -1.062 0.491
C2 -4.710 -0.049 -0.519
C3 -4.193 1.266 -0.144
C4 -3.045 1.113 0.856
C5 -2.268 -0.070 0.555
Я хочу извлечь координаты и сохранить их в матрице под названием атомы. Но содержимое матрицы, которую я получаю:
[[ 0. 0. 0. ]
[-2.268 -2.268 -2.268]
[-0.07 -0.07 -0.07 ]
[ 0.555 0.555 0.555]
[ 0. 0. 0. ]
[ 0. 0. 0. ]]
Что не так с этим кодом?
Но почему вы вообще делаете это так долго? Почему бы просто не использовать loadtxt()?
@wjandrea, как ты это сделаешь? Поделитесь, пожалуйста, ответом.
atoms
— это двумерный массив, но вы индексируете его только одним индексом, поэтому atoms[i]
относится ко всей строке. Когда вы назначаете скаляр (срезу) такого массива, скаляр получает «широковещательную рассылку», т. е. повторяется столько раз, сколько необходимо, чтобы заполнить весь срез (т. е. в данном случае строку).
Спасибо за разъяснения, а что вы предлагаете для решения проблемы? Как мне изменить код?
Я не уверен, почему кто-то проголосовал против этого. Вся информация верна, хотя это не полный ответ, поскольку в коде есть и другие ошибки.
@Another.Chemist Вы не просили решения в вопросе, вы только спросили, что не так. Если вам нужно решение, отредактируйте вопрос, чтобы уточнить это.
Вы читаете каждую строку файла и разделяете ее на 4 строки. Вы пропускаете первый sline[0]
(пока ок).
Но затем вы перебираете оставшиеся строки и присваиваете версию с плавающей запятой строкам 1, 2 и 3 из atoms
:
for i in range(1, 4, 1):
atoms[i] = float(sline[i])
то есть
atoms[1,:] = float(sline[1])
atoms[2,:] = float(sline[2])
atoms[3,:] = float(sline[3])
И вы повторяете это для каждой строки, каждый раз перезаписывая три строки atoms
. atoms[0]
— это все 0, исходное значение.
Последняя строка
C5 -2.268 -0.070 0.555
и это значения в atoms[1:4,:]
. Все, что вы делали с предыдущими строками, было перезаписано.
Хотя я мог бы предложить исправление, я думаю, вам следует решить его самостоятельно. Вы не делаете ничего особенного, поэтому, если вы внимательны к деталям, у вас все получится.
Мне нравится работать в интерактивном сеансе Python, например ipython
, и тестировать строку или блокировать по одному.
В качестве подсказки начните с i=0
и увеличивайте ее с каждой новой строкой. В одну строку напишите что-то вроде
for j in range(3):
atoms[i, j] = float(sline[j+1])
Другими словами, вам нужен отдельный счетчик для строк и столбцов atoms
. Позже вы сможете назначить целые строки atoms
сразу, но для начала узнайте подробности о правильном назначении строк за строками, столбцов за столбцами.
Из вывода видно, что код присваивает неправильные части матрицы, так в чем именно вам нужна помощь? Что вы пробовали? Например, читали ли вы руководство пользователя NumPy, Индексирование на ndarrays?