質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

2742閲覧

指定範囲における近似線の傾きを求めたい

yagi_shu

総合スコア4

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/09/14 04:49

編集2021/09/14 08:55

前提・実現したいこと

Pythonを使って、対象箇所における70cm格子ごとの横断勾配を求めたいです。
想定手順とわからない箇所
1.XYZ値を含むcsvデータの読み込み
2.列ごと(XYZごと)にラベル付け
3.対象地におけるXYの最大値と最小値を抽出
4.XY面における70cm格子の作成
5.各格子内のXZ値を使って、XZ値の近似線の傾きを求める
6.A列B列C列(XYZ)は元の値を据え置き D列に求めた近似線の傾きを挿入
7.csvデータとして出力
D列の横断勾配は70cmごとに区切って対象とした点にリンクする形で挿入したいです。そのため、出力データのA列、B列、C列、D列はすべて同じデータ数となることを想定しています。

データは位置情報(XYZ値)を含む点群データとなっています。
点群はXY軸に対して並べられており、XとYの最小値はそれぞれ0であり、同一の点となっています。

簡易的な説明となってしまい申し訳ございませんが、ご回答よろしくお願いいたします。

###イメージ図
イメージ説明

入力データは実際には下図の通り、XY軸に対してまっすぐに並列されています。
イメージ説明

該当のソースコード

import pandas as pd import csv import numpy as np import sympy as sp import io #入れたいデータを選択 pd.read_csv("〇〇〇") #入れたいデータを選択 df=pd.read_csv("〇〇〇",names=("X","Y","Z")) #CSVを列ごとにラベル付け X=df["X"] Y=df["Y"] Z=df["Z"] #XとYの最大・最小を抽出 Xmax = (max(X)) Xmin = (min(X)) Ymax = (max(Y)) Ymin = (min(Y)) Xi = (Xmax - Xmin)/0.7 Yi = (Ymax - Ymin)/0.7 #70cmの格子の作成 grid_X = Xmin + (0.7+(0.7*Xi))/2 + (0.7*Xi)/2 grid_Y = Ymin + (0.7+(0.7*Yi))/2 + (0.7*Yi)/2 """ わからない箇所 """ list1 = [X] list2 = [Y] list3 = [Z] list4 = [横断勾配] with open('〇〇〇', 'w', newline="") as f: writer = csv.writer(f) for kekka in zip(X,Y,Z,横断勾配): writer.writerow(kekka)

試したこと

np.polyfitを使って、70cm格子内の近似線の傾きを求めることができるのではないかと考えていますが、うまく実行できませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ppaul

2021/09/14 04:58

回答者にとってのわからない箇所 格子とX,Yの関係が不明 何を入力として、どういうものを出力としたいのかが不明。 イメージ図左の赤点はばらついてますが、実際には上記の通り、XY軸に対してまっすぐに並列されています、の意味が不明
yagi_shu

2021/09/14 05:18

入力するCSVデータはA列にX値、B列にY値、C列にZ値が記載されています。このCSVデータの散布図をイメージ図の左としたとき、70cm格子の範囲ごとに横断勾配を求めたいです。その後、A列にX値、B列にY値、C列にZ値、D列に勾配となるCSVデータを出力したいです。 イメージ図は左側を修正いたします。 よろしくお願いいたします。
ppaul

2021/09/14 05:41

例えば格子が2×2の4個だとしましょう。 つまり、70mの格子が縦横140cmの領域を4個に分けている状態です。 このとき、XとYの間隔が35mだとすると、XとYは「0, 35, 70, 105, 140]なのか[17.5, 52.5, 87.5, 122.5]なのか、実は間隔は一定ではないのかのどれなのかがまったくわかりません。
yagi_shu

2021/09/14 06:11

格子の間隔は一定となっており、ppaulさんの例の場合、4点の座標は(35,35)(35,105)(105,35)(105,105)となります。よろしくお願いいたします。
ppaul

2021/09/14 06:57

(0,0)とか(140,0)とかはないのですね。
yagi_shu

2021/09/14 07:14

はい。最大・最小ではなく、各70cm格子の中心となります。 最終的には各70cm格子ごとに近似線の傾きを求めたいと思っております。
ppaul

2021/09/14 07:40

つまり、格子の中には、常に一点しかないということですか?
yagi_shu

2021/09/14 07:44

はい。勾配を計算する場合は格子中に常に一点となります。 しかし、出力の際には、格子の座標は出力せず、入力データのD列に計算した勾配を挿入したいと考えています。
ppaul

2021/09/14 08:03

赤点のイメージ図はないほうがわかりやすいですね。 あと、いくつかわからないことがあります。 格子は縦横それぞれいくつを想定しているのでしょう。 勾配を求めるときは、X軸方向の情報だけをもとに近似をもとめるということでよいのでしょうか。 近似は何次式で近似したいのですか。
yagi_shu

2021/09/14 08:51

承知しました。 格子の数は対象とする範囲によって変わってしまうと考えているため、格子内にデータが存在しない場合には計算を終了するといった形を想定しております。 また、勾配を求める際には、格子内のXZ値のみを考えた2次式の近似式で求めることを想定しております。
guest

回答2

0

概念的な絵を描いてみました.

測定対象の形状が概ね赤線だったとして,そこから得られた計測データ点群が赤丸だとします.
各データが赤線から少しずつ外れているのは,その場所が本当にそのような形状だった(局所的な起伏があった)とか,測定誤差が乗ったとか,そういう事柄によるものです.

1個だけ内側が黄色い点は「外れ値」として描いてみました.

イメージ説明

図の下側は,
「ある区間内のデータだけを用いて,その区間の中心位置の勾配を推定する」話の模式図です.
区間内のデータ点は6個で,その中には外れ値が含まれていますが,
ここでは関数近似の際にはこの外れ値の影響を(RANSACとかその他のロバスト推定を用いるなどして)うまく除去できるのだとしましょう.

残りの5点の並びを一次式(直線)で近似した結果が緑の線です.(もちろん実際に近似計算したわけではなく,それっぽく手書きしたものです)
この場合,この線の傾きがそのまま勾配の推定値となります.

この5点の並びを二次式で近似した結果が青点群で示した放物線です.(同上.概念的な手書きです)
この場合,区間中央での傾きは水色の線のようになるでしょう.

この二つの結果をどう考えるか?

  • 赤い線の勾配を推定したいのだとしたら,一次式の結果の方が好ましく,
  • 局所的な起伏の勾配に興味があるならば,二次式の結果の方が好ましいのかもしれません.

「どうやると良いか?」は,やること次第です.
測定対象や測定データの性質を鑑みて,注意深く計画すべきと思います.

  • 「70cm毎の」推定値を得るために,使用するデータを「各70cmの区間内」に制限すべきなのだろうか?

(図の例で,区間の付近にあるデータ点を数点加えて近似曲線を求めたならば,その形状はどうなるだろうか?)

  • 近似式の自由度はどのくらいが適切なのか?
  • etc

投稿2021/09/17 02:33

編集2021/09/17 02:40
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/09/17 02:36 編集

※これは, ppaul 氏の回答のコメント欄に書いたことを,図を用いて書いたものです. 図を示す他の方法が無いためにこのような形をとりました. 話の内容としては,質問への直接的な「回答」とはなりません.
yagi_shu

2021/09/20 04:17

ご丁寧な解説ありがとうございます。一次式で進めていこうと思います。 まずは70㎝格子のデータを抽出する方法を考えてみようと思います。
guest

0

Yのそれぞれの要素に対して、XとZのデータをもとに勾配(微分)をもとめたいという問題であると理解しました。

Xの長さが100とかあるデータのすべてを使って二次関数で近似すると、データによっては非常に大きな誤差が出ますので、それは止めた方が良いでしょう。
計算量も考えると、勾配を求めたい点とその両側の二点の合わせて三点を使って近似し、求めたい点における微分係数を求めるのが良いと思います。
この場合、Xの最小値と最大値では一方の側の点が存在しないので、この場合に限って特殊な処理が必要になります。

具体的にどうやるかについては、大きく分けて二通りあります。

方法1
forで回しながら一点ずつ計算していく方式です。この場合は、np.polyfitを使います。性能は遅くなりますが、コーディングは比較的簡単です。

方法2
全体を一度に計算する方式です。まだ深くは考えていませんが、二次関数近似式の二次の項の係数がゼロの場合を特別扱いしなければならないのではないかと思います。たぶんマスクをして計算することになりますが、うまく作れれば性能はずっと速いでしょう。

アルゴリズムを知りたいのか、Pythonのテクニックを知りたいのかどちらでしょうか。
全部やってほしいというのは求めないで下さい。

投稿2021/09/14 11:15

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yagi_shu

2021/09/15 02:34

ご回答いただきありがとうございます。係数ゼロ、勾配がゼロの場合も結果として抽出したいと考えているため、方法1でのコーディングを検討してみます。np.polyfitを使った方法はいくつか試したのですが、もう一度チャレンジしてみます。
fana

2021/09/15 04:56

> 勾配を求めたい点とその両側の二点の合わせて三点を使って… {どんな関数を,何点使って}推定するか,というのは,実装が楽だとか処理が早いとかよりも 「やろうとしていることの意味」から決定した方がよいのでは. ・勾配とは,どの程度 局所的/大域的 な勾配を考えているのか ・データが「70cm間隔でZ値を測定した測定データ」だったりした場合,測定誤差の影響をどう扱いたいのか? 等々. (例えば3点に2次関数を当てはめたら必ずその3点を通る形になりそうですが,仮に各点での測定誤差が相応にあるとしたら,本当にその方法でいいのか? ってことになりませんか?)
yagi_shu

2021/09/15 10:52

コメントいただきありがとうございます。求めたい勾配は70㎝格子の範囲での勾配であり、まずは一格子ずつ格子内に含まれるデータのXとZの値のみを使用して計算を行いたいと考えています。その際、勾配は近似式の二次の項の係数を勾配としてみなしたいと考えています。
ppaul

2021/09/16 04:56

** 勾配は近似式の二次の項の係数を勾配としてみなしたいと考えています。 それは間違っています。 近似式の二次の項の係数の2倍と近似式の一次の項の係数の和が勾配の近似値です。 **例えば3点に2次関数を当てはめたら必ずその3点を通る形になりそうですが,仮に各点での測定誤差が相応にあるとしたら,本当にその方法でいいのか? ってことになりませんか? 測定誤差の問題もありますが、勾配を求めたいときには二次関数は極値を一つしか持たないという理由で勾配に関しては誤差がかなり大きくなる可能性があります。データがおとなしければ二次関数でも大丈夫かもしれません。 回答には書きませんでしたが、私が実装するなら、二次関数の他に、極値を二つ持つことができる三次関数で四点にするのと、四次関数で五点にするのをやってみて、その結果でどれにするかを決めるでしょう。
fana

2021/09/16 05:25 編集

> コメントいただきありがとうございます。求めたい勾配は70㎝格子の範囲での勾配であり、まずは一格子ずつ格子内に含まれるデータのXとZの値のみを使用して計算を行いたいと考えています というコメントだと,格子内に複数のデータ点があるかのように読めるのだけど, 他方,[質問への追記・修正、ベストアンサー選択の依頼]には > はい。勾配を計算する場合は格子中に常に一点となります。 という話もあるようだし,そこらへんがよく把握できていないけど… 自分なら「なるべく多くのデータ点を用いて」「なるべく次数の少ない関数を当てはめる」ような方向を考えるかな. 何らかの理由で70[cm]の範囲のデータしか使わないのだとしても,そのデータの並びを目視した時点で「明らかに曲線形状である」と見えない(ようなスケールでの話)ならば,1次式が最もよい.
fana

2021/09/16 05:23

自分が立ってる床の傾きを考えるときに,ふつーはそこに敷いてあるカーペットの毛による凹凸を考えねぇよなっていう. でも,「0.2[mm]間隔で」とか言われたら話は全然変わるわけで. ↑は極端な話だけど,「勾配とは,どの程度 局所的/大域的 な勾配を考えているのか」ってのはそういう話ね. 求めようと考えている「勾配」というのが70[cm]なる範囲において優位に変動し得るのだとして扱わねばならないのか否か. 変動し得るのだとしてそれはどの程度の話なのか? そういう視点がまず前提としてちゃんとあるのかな? というのが気になったのでコメントしてみた次第.
yagi_shu

2021/09/16 07:46

コメントありがとうございます。 使用データは明らかな曲線形状ではないものを使用いたします。まずは70㎝格子ごとに該当する点を抽出し、簡易的に一次式で計算してみようと思います。 その後、ppaulさんからのアドバイスの通り、二次、三次、四次…と検討してみたいと思います。 また、「勾配を計算する場合は格子中に常に一点」というのは、わかりづらい表現で申し訳ございません。入力データを70㎝格子に分け、格子内を計算した結果、一つの格子に答えが一つになるという意味です。 たびたびご検討いただきありがとうございます。
fana

2021/09/16 08:19

> 二次、三次、四次… 曲線形状の自由度を増やすほど,「見た目の当てはまり具合」は良くなる点に注意してください. (完全に残差なく当てはまる=データ点全てを通る ような曲線が引けたとして,その曲線のある地点での傾きがあなたの考えている「勾配」をうまく表すとは限らない)
ppaul

2021/09/16 22:32

私はこの質問を読んで、求められているのは道路わきの法面の横方向の凹凸を調べるような問題なのかなと思いました。 そういう場合は、細かい凹凸は無視して全体の形状を知りたいのだろうと思って回答したのですが、例えばアスファルトの道路の局所的な細かい凹凸を知りたいような問題であればfanaさんが書かれているような方法の方が良いだろうと思います。
fana

2021/09/17 02:45 編集

あれ? > 細かい凹凸は無視して全体の形状を知りたいのだろう …と私も想像していますよ. だからこそ,話として不要な細かい凹凸に捉われた結果を得てしまわないように,という方向のコメントをしているつもりです. 曲線の自由度(e.g. 多項式の次数)を増やしすぎると測定誤差や取るに足らない凹凸にオーバーフィッティングしてしまい,面白くない「勾配」が得られる結果になり得るから注意,っていう. それ故の「一次式」推し. #ここまで書いたコメントと同じ話を「別の回答」の形で絵付きで示しました. (性質としては,質問内容に対する「回答」ではないのですが,他に絵を貼る手段がなかったので.)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問