#python #dataframe #for-loop
#python #фрейм данных #для цикла #for-цикл
Вопрос:
Я совсем новичок в Python, поэтому не могу решить тривиальную проблему. Мне нужно создать составную линию, состоящую из прямых линий, соединяющих некоторые точки. У меня есть текстовый файл с набором 2D (x-y) координат точек. Я правильно прочитал файл и сохранил данные в фрейме данных. Затем с помощью цикла for я беру две последовательные точки и нахожу коэффициенты (coefficients_i) линий, проходящих через точки, с помощью функции numpy polyfit. Затем я создаю отдельные сегменты линий, соединяющих точки (yaxis_i), но чего я не могу сделать, так это создать единую составную линию, состоящую из разных сегментов. Моя строка должна быть: yaxis_i yaxis_(i 1) … yaxis_ (i n) и я хотел бы, чтобы он был сохранен в фрейме данных, чтобы я мог легко его отобразить. Я пытался добавить разные сегменты в numpy.ndarray, но, похоже, это не работает. Вот код:
d = []
e = []
for i in range(len(ln_pts)-1):
x_i = [ln_pts.iat[i 1,0],ln_pts.iat[i,0]]
y_i = [ln_pts.iat[i 1,1],ln_pts.iat[i,1]]
coefficients_i = np.polyfit(x_i, y_i, 1)
print('m',i,' =', coefficients_i[0])
print('q',i,' =', coefficients_i[1])
# Compute the values of the lines (yaxis) in a given domain (xaxis)
polynomial_i = np.poly1d(coefficients_i)
xaxis_i = np.arange(x_i[1],x_i[0])
yaxis_i = polynomial_i(xaxis_i)
d.append(xaxis_i)
e.append(yaxis_i)
Есть идея решить эту проблему?
Спасибо
Комментарии:
1. Разве точки, которые вы читаете из файла, уже не описывают строку так, как вы хотите? Почему махинации с полиномиальными подгонками?
2. Если вы хотите увеличить плотность точек, вам должна быть достаточно простой интерполяции .
3. Кроме того, пожалуйста, правильно отформатируйте свой код. Код python с неправильным отступом является недопустимым кодом python.
Ответ №1:
Вам не нужно создавать полиномиальные соответствия, а затем интерполировать более плотный набор x
значений. Эта операция называется кусочно-линейной интерполяцией. У Numpy уже есть interp()
, который делает это за вас.
Если вы не используете pandas ниже по потоку, также нет необходимости вводить pandas в уравнение.
pts = np.loadtxt('myfile.txt')
wanted_xpts = np.linspace(pts[:, 0].min(), pts[:, 0].max(), 10000)
interp_ypts = np.interp(wanted_xpts, pts[:, 0], pts[:, 1])
plt.plot(pts[:, 0], pts[:, 1], 'or')
plt.plot(wanted_xpts, interp_ypts, '-k')
plt.show()
Вам обязательно использовать цикл? Это ненужно и неэффективно, но вы все равно идете сюда:
Ваш код в основном подходит для этой работы. Нет необходимости вычислять полиномиальную подгонку. Вы можете просто использовать interp
с x_i
и y_i
.
d, e = [], []
for i in range(len(ln_pts)-1):
x_i = [ln_pts.iat[i 1,0],ln_pts.iat[i,0]]
y_i = [ln_pts.iat[i 1,1],ln_pts.iat[i,1]]
xaxis_i = np.linspace(x_i[1], x_i[0], 10)
yaxis_i = np.interp(xaxis_i, x_i, y_i)
d.append(xaxis_i)
e.append(yaxis_i)
Теперь у вас есть все новые точки x и y из каждого сегмента в отдельных списках в d
и e
. Вы можете просто использовать np.hstack
, чтобы объединить все это в один одномерный массив.
xpts = np.hstack(d)
ypts = np.ystack(e)
Затем вы можете назначить их столбцам фрейма данных, если хотите.
Комментарии:
1. Спасибо, действительно очень полезно, но это остается проблемой цикла for. Мне нужно реализовать цикл for, который выполняет работу для каждой пары точек и объединяет результаты в один вектор.
2. @EnricoB Почему? Если это не упражнение, на самом деле нет причин делать это таким образом. Добавление к массивам numpy — это медленная операция, если вы можете сделать это за один раз (как вы можете в этом случае), вы должны.
3. Хорошо, теперь я наконец понял это. Кажется, все работает нормально. Спасибо за вашу помощь, Пранав