🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

2702閲覧

点の座標と矩形のマッチングについて

mi2

総合スコア63

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2019/10/08 10:27

考えていること

点の座標のデータx,yが、面積の座標を表すデータx1,y1,x2,y2,x3,y3,x4,y4(左上, 右上, 右下, 左下)の中に入ってくるかどうかを判定し。フラグを立てたいです。
最終的には、dfの右側に、どのポジションにいたかを付与するような形を取りたいと考えております。

例えば、(x,y) = (1,1)のとき、(x1,y1)=(0,5), (x2,y2)=(5,5), (x3,y3)=(5,0), (x4,y4)=(0,0)の場合、
「矩形の中に入ってくるため、対応する名前をフラグとして立てる」ようなイメージです。

位置座標情報

df = x y, その他のカラム... 440 495 440 462 451 507 449 507 443 506

面積の座標を表すデータx1,y1,x2,y2,x3,y3,x4,y4とそれに対応する名前(position(a, b, c, …))

df_position = x1,y1,x2,y2,x3,y3,x4,y4,position, その他のカラム... 556 250 2371 250 2371 672 556 672 a 551 261 555 675 563 680 577 711 b 511 257 2322 256 2322 680 511 680 c 543 86 2311 86 2311 515 543 515 d

作成したいデータフレーム

df_new x y area, その他のカラム... 440 495 該当するエリア 440 462 該当するエリア 451 507 該当するエリア 449 507 該当するエリア 443 506 該当するエリア

困っていること

座標とのマッチングはできたのですが、面積の中に点がいるかどうかのマッチングがうまくできない点、
該当するエリアが複数対応するときに、x,yの組み合わせ(レコード自体)を増やしてダブルカウントにしたい点、
その部分で困っております。

お知恵を拝借できましたら幸いです。
何卒よろしくお願い申し上げます。

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

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

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

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

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

guest

回答1

0

ベストアンサー

点 (x,y) が長方形に含まれるかどうかは以下の不等式で判定できます。

x >= 左上の x 座標 and x <= 右下の x 座標 and y >= 左上の y 座標 and y <= 右下の y 座標

なので、点が含まれる領域を返す関数を作成し、DataFrame.apply で適用すればいいと思います。

python

1import pandas as pd 2from io import StringIO 3 4positions = pd.read_csv( 5 StringIO( 6 """x,y 7556,250 8556,255 9451,507 10449,507 11443,506 12""" 13 ) 14) 15 16area = pd.read_csv( 17 StringIO( 18 """x1,y1,x2,y2,x3,y3,x4,y4,position 19556,250,2371,250,2371,672,556,672,a 20551,261,555,675,563,680,577,711,b 21511,257,2322,256,2322,680,511,680,c 22543,86,2311,86,2311,515,543,515,d 23""" 24 ) 25) 26 27 28def find_area(point, area): 29 # 点 point が領域 area に含まれるかどうか 30 contains = ( 31 (point.x >= area.x1) 32 & (point.x <= area.x3) 33 & (point.y >= area.y1) 34 & (point.y <= area.y3) 35 ) 36 37 # 点 point が含まれる領域 38 area_id = area.loc[contains, "position"] 39 40 return list(area_id) 41 42 43positions["area"] = positions.apply(find_area, axis=1, area=area) 44positions = positions.explode("area") 45 46print(positions) 47# x y area 48# 0 556 250 a 49# 0 556 250 d 50# 1 556 255 a 51# 1 556 255 d 52# 2 451 507 NaN 53# 3 449 507 NaN 54# 4 443 506 NaN

投稿2019/10/08 11:01

編集2019/10/08 13:38
tiitoi

総合スコア21956

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

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

mi2

2019/10/08 12:24 編集

ありがとうございます。 areaを複数行にしたい場合は, 関数適用後のpositionをいじるのがよいのでしょうか。 それとも関数内に記述した方がよいのでしょうか。 ‘‘‘x y area 556 250 a 556 250 d ‘‘‘
mi2

2019/10/08 13:59

ありがとうございます。大変勉強になりました。
mi2

2019/10/08 14:38

お忙しいところ大変恐縮ですが、もし可能でしたらまた引っかかって困っていることがございまして、ご教示頂けましたら幸いです。 大変申し訳ございません。
mi2

2019/10/09 09:10

すみません、もしこれ4点が(左上, 右上, 右下, 左下)の順に入っていない場合を想定すると、df_position のデータをソートすることを想定しないといけないでしょうか。 contains = ( (point.x >= area.x1) & (point.x <= area.x3) & (point.y >= area.y1) & (point.y <= area.y3) ) の最大最小みたいなものを関数の中に組み込む必要がありますでしょうか。
tiitoi

2019/10/09 09:24

ソートは必要ないです。 長方形に点が含まれるかどうかが回答の不等式で判定できることは理解されていますか? (x1 y1) (x3 y3) を左上、右下に該当するものに変更すればよいです。
tiitoi

2019/10/09 09:26

それとも行ごとに 左上, 右上, 右下, 左下 の順番が異なるということでしょうか? もしそうであれば、(x1 y1) が左上、(x3 y3) が右下となるように行ごとのソートが必要です。
mi2

2019/10/09 12:44 編集

> 長方形に点が含まれるかどうかが回答の不等式で判定できることは理解されていますか? はい、こちら2点の座標を見れば良いということは図を手書きして理解させて頂きました。 > それとも行ごとに 左上, 右上, 右下, 左下 の順番が異なるということでしょうか? すみません、こちらになります。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問