У меня есть входной файл с именем "cmp_twtt_amp_rho", длина которого 7795074. Я хотел бы рассчитать скорость звука, с, для каждой строки, где:
C (i) = rho (i-1) * c (i-1) * (-1 ампер (i)) / rho (i) * (ампер (i) -1)
Используя начальное предположение с = 1450.
Я написал цикл for, который, по моему мнению, будет работать, однако со временем он становится все медленнее, настолько, что его использование невозможно в его текущем формате.
Может ли кто-нибудь помочь мне ускорить этот кусок кода, пожалуйста?
data=np.genfromtxt('./cmp_twtt_amp_rho')
cmp_no=data[:,[0]]
twtt=data[:,[1]]
amp=data[:,[2]]
rho=data[:,[3]]
cs=[]
for i in range(1,len(amp-1)):
if i == 1:
print "Using an initial guess of 1450 m/s"
c = (rho[i-1]*1450*(-1-amp[i]))/(rho[i]*(1-amp[i]))
cs = np.append(c,cs)
elif twtt[i] == 0:
print "Reached new cmp #: ",cmp_no[i],"as twwt has re-started at ",twtt[i]
c = 1450
cs = np.append(c,cs)
else:
print i
c = (rho[i-1]*cs[i-1]*(-1-amp[i]))/(rho[i]*(1-amp[i]))
cs = np.append(c,cs)
print min(cs), max(cs)
print len(cs)
3 ответа
np.append
должен перераспределить весь массив, ведь это плохо, но не единственная проблема. Вы добавляете cs
в c
, а не наоборот, это означает, что cs
будет изменен на обратный и cs[i-1]
на самом деле будет первым c
.
В общем случае лучше предварительно выделить ваши массивы:
cs = np.zeros(len(amp-1))
Затем просто установите значения напрямую:
cs[i] = c
Примерно так должно быть немного быстрее:
cs=np.zeros(len(amp-1))
print "Using an initial guess of 1450 m/s"
cs[1] = (rho[i-1]*1450*(-1-amp[i]))/(rho[i]*(1-amp[i]))
for i in range(2,len(amp-1)):
if twtt[i] == 0:
print "Reached new cmp #: ",cmp_no[i],"as twwt has re-started at ",twtt[i]
cs[i] = 1450
else:
print i
cs[i] = (rho[i-1]*cs[i-1]*(-1-amp[i]))/(rho[i]*(1-amp[i]))
Массивы Numpy на самом деле не предназначены для добавления (NumPy необходимо каждый раз выделять полный новый массив и копировать старые данные). Вы, вероятно, не хотите делать это в цикле.
Лучше использовать структуру данных, предназначенную для такого рода вещей - как правило, list
python отлично справляется с добавлением, поэтому я предлагаю вам сохранить данные в списке и добавлять их по мере необходимости. Затем, в конце, если вам нужен полный набор данных в виде массива, вы можете преобразовать обратно в этот момент.
Я бы рекомендовал просто изменить cs.append(c)
вместо cs = np.append(c, cs)
Присоединение к массивам происходит очень медленно, так как вам приходится каждый раз выделять новый массив. Выполнение этого в цикле почти всегда приводит к снижению производительности.
Вместо добавления в цикл или даже использования цикла на уровне Python вы можете сделать это намного быстрее с помощью векторизованных операций и накопленного продукта:
multipliers = rho[:-1] * (-1 - amp[1:]) / (rho[1:] * (1 - amp[1:])
cs = np.cumprod(np.insert(multipliers, 0, 1450))
(insert
также требует выделения всего нового массива, но это нормально, поскольку мы делаем это только один раз.)
Кроме того, у вас, вероятно, есть ошибка знака. Ваша формула говорит (amp(i) - 1)
, а ваш код - (1 - amp[i])
. Я выбрал совпадение с вашим кодом, но вам может потребоваться исправить это.
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.