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

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

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

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

Python

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

Q&A

解決済

2回答

1944閲覧

csvの行ごとに計算を行いたい

yagi_shu

総合スコア4

CSV

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

Python

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

0グッド

0クリップ

投稿2021/05/18 05:53

編集2021/05/18 09:09

前提・実現したいこと

csvデータに含まれる位置情報(xyz値)のデータを行列計算によって回転・移動を行いたいと考えています。具体的には1.原点中心の回転とするために平行移動を行う。2.原点中心に回転を行い、位置情報データをY軸を基準とするように回転を行う。の2点を行いたいと考えています。

1.については起点なる位置の抽出ができたのですが、2.の回転のフェーズにおいて、csvデータの行ごとの計算方法がわかりません。

座標の変換を行って、xyzを再びcsvデータとして出力する方法はわかるのですが、回転の計算の部分のみわかりません。よろしくお願いいたします。
私が考えている平行移動及び回転のイメージは以下の図のようになっております。
イメージ説明

以下、csvデータの一部分です。
X        Y        Z
18840.76758 -30595.92773 26.81204796
18840.75781 -30595.89648 26.83104706
18840.7832 -30595.90625 26.82704735
18840.78516 -30595.91016 26.81804657
18840.76758 -30595.9082 26.8090477
18840.75781 -30595.9082 26.79904747
18840.76172 -30595.91211 26.7920475
18840.77148 -30595.92188 26.7770462
18840.73633 -30595.875 26.81004715
18840.75781 -30595.88477 26.80404663

また、各行が位置を表しており、これらのデータを以下の式を使って座標変換したいと考えています。
イメージ説明

該当のソースコード

import pandas as pd import csv import numpy as np import sympy as sp #入れたいデータを選択 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)) Ymax = (max(Y)) Xmin = (min(X)) Ymin = (min(Y)) print(df[df['X'] == df.min(axis=0)['X']]) print(df[df['Y'] == df.min(axis=0)['Y']]) x1 = df[df['Y'] == df.min(axis=0)['Y']]['X'].values[0] y1 = df[df['Y'] == df.min(axis=0)['Y']]['Y'].values[0] x2 = df[df['X'] == df.min(axis=0)['X']]['X'].values[0] y2 = df[df['X'] == df.min(axis=0)['X']]['Y'].values[0] #回転すべき角度を求める kijunn = (x2 - x1) / (y2 - y1) θ = abs(np.degrees(np.arctan(kijunn))) print(θ) sinθ = np.sin(np.radians(θ)) cosθ = np.cos(np.radians(θ)) #この式を使って回転・移動を行うため、csvに含まれる位置情報データに適応したいです。 u = ( X*(cosθ) + Y*(sinθ) - x1 ) v = ( -X*(sinθ) + Y*(cosθ) - y1 )

試したこと

defやsympyを使って試してみたのですが、csvデータの行ごとの計算がうまくいきませんでした。

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

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

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

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

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

TakaiY

2021/05/18 08:45

やりたいことがよくわかりません。 簡単な入力の例(カラム名付きで)と、想定される出力の例と、それをどのように算出するのかについて説明してください。
yagi_shu

2021/05/18 08:49

承知いたしました。修正いたします。
TakaiY

2021/05/18 09:15

やりたいことと、csvデータはどのような関係ですか? やりたいことには、(x1, y1) (x2, y2)の2点しか出てきませんが、csvにはx, y, zの点が複数出てきます。 また、出力はどのような出力を想定していますか?
TakaiY

2021/05/18 09:25

もしかして、全ての点をθ度(ラジアン?)z軸周りに回転させたいということですか?
yagi_shu

2021/05/18 09:26

図に示した長方形は簡易的に表したもので、実際には複数の位置情報データ(点群データのようなもの)があり、それらを座標変換(平行移動)したいと考えております。(x1, y1) (x2, y2)の2点はY軸を基準とした回転を行うために求めたものになります。図に示した青点を原点に移動し、青点を基準として回転を行いたいと考えています。出力されるものは入力データと同じようなものを想定しており、各セルに位置情報が入る形を想定しています。
jbpb0

2021/05/18 10:23

質問の図だと、青点が座標原点になるように並行移動させてから、回転させてます 一方、質問の式は、先に回転させてから、並行移動させてます 両者の結果は一致しません 先に回転させると、その結果では青点の座標はx1, y1ではないので、x1, y1を引いても青点は原点に移動しません
jbpb0

2021/05/18 10:29

質問の図のように、二つのステップに分けて処理する方が、わかりやすいと思います ステップ1は並行移動 x, yからそれぞれx1, y1を引く ステップ2は回転 下記Webページの計算をした結果のX, Yが回転後の座標 https://mathwords.net/heimenkaiten
yagi_shu

2021/05/18 11:12

for文等を使って各行ごとに移動と回転を行っていく方がいいのでしょうか?
guest

回答2

0

移動量と角度を算出するところが問題でなければ、以下のようにすればできるでしょう。

例では元のdfに入れていますが、別のDFがよければ空のものを作って入れます。
また、移動と回転を別にしていますが、一度にすることもできます。

python

1import pandas as pd 2df = pd.DataFrame({'x': [4, 7, 4], 'y': [3, 6, 8], 'z': [3, 3, 3]}) 3 4# x方向に -4, y方向に -3 移動 5df["xx"] = df["x"] - 4 6df["yy"] = df["y"] - 3 7 8# 45度回転 9df["xxx"] = df["xx"] * math.cos(math.radians(45)) + df["yy"] * math.sin(math.radians(45)) 10df["yyy"] = -1 * df["xx"] * math.sin(math.radians(45)) + df["yy"] * math.cos(math.radians(45))

元と計算後のdf

text

1 2 x y z 30 4 3 3 41 7 6 3 52 4 8 3 6 7 8import math ... 9 x y z xx yy xxx yyy 100 4 3 3 0 0 0.000000 0.000000 111 7 6 3 3 3 4.242641 0.000000 122 4 8 3 0 5 3.535534 3.535534

投稿2021/05/18 10:22

TakaiY

総合スコア12765

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

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

yagi_shu

2021/05/18 11:17

考えている出力の形が以下のようなに変換後のXYZとなるようなcsvデータを想定しているのですが、そもそも出力の形を変えた方がいいのでしょうか? list1 = [変換後のX] list2 = [変換後のY] list3 = [Z] with open('〇〇〇', 'w', newline="") as f: writer = csv.writer(f) for kekka in zip(変換後のX,変換後のY,Z): writer.writerow(kekka)
TakaiY

2021/05/18 14:07

いやいや。 もとのデータをpandas のdataframeに読み込んであって、dfとして結果を算出しているのですから、できあがったdfを to_csv メソッドでcsvに書き出せばいいのですよ。 ppaulさんの回答にずばりが出ていますから、そのdfをto_csvで出力してみてください。
yagi_shu

2021/05/19 07:22

丁寧なご対応ありがとうございました。無事、想定していたものができました。
guest

0

ベストアンサー

以下でできます。

python

1import pandas as pd 2import numpy as np 3import io 4 5indata = '''X Y Z 618840.76758 -30595.92773 26.81204796 718840.75781 -30595.89648 26.83104706 818840.7832 -30595.90625 26.82704735 918840.78516 -30595.91016 26.81804657 1018840.76758 -30595.9082 26.8090477 1118840.75781 -30595.9082 26.79904747 1218840.76172 -30595.91211 26.7920475 1318840.77148 -30595.92188 26.7770462 1418840.73633 -30595.875 26.81004715 1518840.75781 -30595.88477 26.80404663''' 16 17with io.StringIO(indata) as f: 18 df = pd.read_csv(f, sep=' +', engine='python') 19 20print(df) 21 22x1 = df[df['Y'] == df.min(axis=0)['Y']]['X'].values[0] 23y1 = df[df['Y'] == df.min(axis=0)['Y']]['Y'].values[0] 24x2 = df[df['X'] == df.min(axis=0)['X']]['X'].values[0] 25y2 = df[df['X'] == df.min(axis=0)['X']]['Y'].values[0] 26 27#回転すべき角度を求める 28kijunn = (x2 - x1) / (y2 - y1) 29θ = abs(np.degrees(np.arctan(kijunn))) 30print(θ) 31 32sinθ = np.sin(np.radians(θ)) 33cosθ = np.cos(np.radians(θ)) 34 35def u(row): 36 return (row['X']-x1)*cosθ + (row['Y']-y1)*sinθ 37 38def v(row): 39 return -(row['X']-x1)*sinθ + (row['Y']-y1)*cosθ 40 41df['u'] = df.apply(u, axis=1) 42df['v'] = df.apply(v, axis=1) 43 44print(df)

実行結果は以下です。

python

1>>> print(df) 2 X Y Z u v 30 18840.76758 -30595.92773 26.812048 0.000000 0.000000 41 18840.75781 -30595.89648 26.831047 0.007527 0.031865 52 18840.78320 -30595.90625 26.827047 0.024389 0.010515 63 18840.78516 -30595.91016 26.818047 0.024081 0.006152 74 18840.76758 -30595.90820 26.809048 0.009957 0.016801 85 18840.75781 -30595.90820 26.799047 0.001552 0.021782 96 18840.76172 -30595.91211 26.792047 0.002922 0.016425 107 18840.77148 -30595.92188 26.777046 0.006338 0.003044 118 18840.73633 -30595.87500 26.810047 0.000000 0.061294 129 18840.75781 -30595.88477 26.804047 0.013498 0.041938

ファイルに保存したいと言うことでしょうか。

python

1df2 = df[['u', 'v', 'Z']].rename(columns={'u': 'X', 'v': 'Y'}) 2print(df2) 3df2.to_csv('out.csv', header=None) 4

で、

python

1>>> print(df2) 2 X Y Z 30 0.000000 0.000000 26.812048 41 0.007527 0.031865 26.831047 52 0.024389 0.010515 26.827047 63 0.024081 0.006152 26.818047 74 0.009957 0.016801 26.809048 85 0.001552 0.021782 26.799047 96 0.002922 0.016425 26.792047 107 0.006338 0.003044 26.777046 118 0.000000 0.061294 26.810047 129 0.013498 0.041938 26.804047

の中身が'out.csv'に出力されます。

投稿2021/05/18 10:37

編集2021/05/18 22:22
ppaul

総合スコア24666

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

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

yagi_shu

2021/05/18 11:03

回答いただきありがとうございます。出力データは入力データと同じようにcsv内で変換後の位置情報(xyz)が各セルに挿入されているものをイメージしています。わかりづらく申し訳ないのですが、よろしくお願いいたします。
ppaul

2021/05/18 22:23

ファイルに出力したいということらしいので、回答に追加しました。
yagi_shu

2021/05/19 07:21

想定していたものができました。対応いただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問