Создание фрейма данных pandas из numpy.ndarray внутри цикла for

#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. Хорошо, теперь я наконец понял это. Кажется, все работает нормально. Спасибо за вашу помощь, Пранав