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

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

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

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

Q&A

解決済

3回答

596閲覧

三次元動作解析装置で得られた位置座標データから角度を一括で算出する方法

KYuki1218

総合スコア26

Python

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

0グッド

0クリップ

投稿2022/09/17 09:45

前提

三次元動作解析装置で得られた位置座標データから,各フレームの角度情報の算出を考えております。座標を手で入力して算出するための計算式はわかったものの,全てのフレームを一括で算出する方法が分かりません…

実現したいこと

三次元動作解析装置で得られた位置座標から,角度を1〜12000フレーム分を一括で算出する。

  • 膝関節の屈伸(hipとkneeおよびkneeとankleをそれぞれ結んだ線の角度)
hip_xhip_yhip_zknee_xknee_yknee_zankle_xankle_yankle_z
1725-571418744-260984902-13976
2720-561420736-264988898-13199
3

出力例:
1 150°
2 152°
3 152°



12000 90°

試したこと

1フレームのhipとkneeとankleの位置座標は手入力で入れています。

Python

1hip = np.array([ 725, -57, 1418]) 2knee = np.array([ 744, -260, -264]) 3ankle = np.array([902, -139, 76]) 4 5f = knee - hip 6t = ankle - knee 7 8cos_theta = np.dot(f, t) / (np.linalg.norm(f) * np.linalg.norm(t)) 9 10theta = np.arccos(cos_theta) * 180 / np.pi 11knee_angle = round(theta, 1) 12print("knee_angle:", knee_angle, "°") 13 14#TCC: 152.8

補足情報(FW/ツールのバージョンなど)

  • jupyter notebookを使用
  • プログラミングは初学者レベル

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

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

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

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

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

Sobasenbei

2022/09/17 10:19

12000フレーム分の位置座標全部手入力で角度の計算だけプログラムに任せる感じですか
meg_

2022/09/17 10:21

> 角度を1〜12000フレーム分を一括で算出する。 データフレームから1行ずつデータを取り出して計算することは出来るが、”一括で”処理する方法が分からないので教えてほしい、という質問ですか? それともデータフレームから1行ずつデータを取り出す方法も分からない、という質問でしょうか?
KYuki1218

2022/09/17 10:31

言葉足らずで大変申し訳ございません。 位置座標をデータフレームとして読み込みはできており,1フレーム毎に手入力であれば角度を算出はできるものの,12000フレーム分を全て手作業で行うのは非現実であるため,1行ずつの角度算出をプログラムに任せられたらと思っております。
meg_

2022/09/17 10:49

・現在のコードでは計算結果をprint出力していますがこの仕様はそのままでしょうか? ・質問のコードを関数化することは出来ますでしょうか? ※ コードはimport文含めて書かれると回答者に分かりやすいです。 ※ 追加の情報は質問本文に追記なさってください。
Sobasenbei

2022/09/17 10:50

ndarrayは変なことしなくてもリストごとにそのまま計算できます。 上の例だとf=knee-hipの計算をしてますよね。 kneeもhipも一次元リストですが二次元にしてもちゃんと計算してくれます
KYuki1218

2022/09/17 11:33

建設的なコメントありがとうございます。 ・"実現したいこと"の出力例のような形式を考えておりますが,可能であれば,各行の角度を表の最後に追加できると嬉しいです。 ・非エンジニア(医療職)のため関数の作成方法は分かりません… なお,importからデータの読み込みは下記の通りです。 import pandas as pd import numpy as np df = pd.read_csv('フォルダ名.csv')
KYuki1218

2022/09/17 11:35

Sobasenbei様:私の知識が疎いため,具体的な方法をご教示いただけますと嬉しいです。
meg_

2022/09/17 11:51

お手数ですが、情報の追加・修正は質問本文へ反映お願いします。この欄ですと他の回答者の目に触れにくいのがその理由となります。
Sobasenbei

2022/09/17 11:57

pandasのDataFrameを使ってるなら、たとえば df["hip_x"]-df["knee_x"] と書けばそれだけで12000個の値全部計算してくれます。 出力の型はSeriesと言ってpandasの一次元リストみたいなもんです
KYuki1218

2022/09/17 12:10

meg_様:質問本文とはどこでしょうか。始めたばかりで分からず,投稿するボタンとは違うのでしょうか。
meg_

2022/09/17 12:14

この欄は”質問への追記・修正の依頼”欄です。 質問を編集したいときは質問欄の左下にある”編集”を押してください。
KYuki1218

2022/09/17 12:36

ご教示いただきありがとうございます(基本的な機能かもしれないのに,すみません…)。また,私の実現したことを丁寧に汲み取ってご尽力いただきましたことも心から感謝申し上げます。
guest

回答3

0

効率の良いコードではありませんが、質問者さんのコードを生かしたプログラムを作成しました。
参考になさってください。

Python

1print(df) 2# hip_x hip_y hip_z knee_x knee_y knee_z ankle_x ankle_y ankle_z 3#0 725 -57 1418 744 -260 984 902 -139 76 4#1 720 -56 1420 736 -264 988 898 -131 99 5 6knee_angles = np.zeros(len(df)) 7for i, v in df.iterrows(): 8 hip = v[["hip_x", "hip_y", "hip_x"]].values 9 knee = v[["knee_x", "knee_y", "knee_z"]].values 10 ankle = v[["ankle_x", "ankle_y", "ankle_z"]].values 11 12 f = knee - hip 13 t = ankle - knee 14 15 cos_theta = np.dot(f, t) / (np.linalg.norm(f) * np.linalg.norm(t)) 16 17 theta = np.arccos(cos_theta) * 180 / np.pi 18 knee_angle = round(theta, 1) 19 knee_angles[i] = knee_angle 20 21df["knee_angle"] = knee_angles 22 23print(df) 24# hip_x hip_y hip_z knee_x knee_y knee_z ankle_x ankle_y ankle_z knee_angle 25#0 725 -57 1418 744 -260 984 902 -139 76 146.9 26#1 720 -56 1420 736 -264 988 898 -131 99 148.1

投稿2022/09/17 12:10

meg_

総合スコア10580

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

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

KYuki1218

2022/09/17 12:40

先に先に回答して頂いた方をベストアンサーと致しました。色々と汲み取って頂いたのにも関わらず申し訳ございません…
guest

0

ベストアンサー

python

1import pandas as pd 2import numpy as np 3import io 4 5csv_data = ''' 6hip_x,hip_y,hip_z,knee_x,knee_y,knee_z,ankle_x,ankle_y,ankle_z 7725,-57,1418,744,-260,-264,902,-139,76 8720,-56,1420,736,-264,988,898,-131,99 9''' 10df = pd.read_csv(io.StringIO(csv_data)) 11 12# 13def calc_knee_angle(args): 14 f, t = args 15 cos_theta = np.dot(f, t) / (np.linalg.norm(f) * np.linalg.norm(t)) 16 theta = np.arccos(cos_theta) * 180 / np.pi 17 return round(theta, 1) 18 19hip = df.filter(regex='hip').apply(np.array, axis=1) 20knee = df.filter(regex='knee').apply(np.array, axis=1) 21ankle = df.filter(regex='ankle').apply(np.array, axis=1) 22f = knee - hip 23t = ankle - knee 24knee_angle = pd.concat([f, t], axis=1).apply(calc_knee_angle, axis=1).map('{}°'.format) 25 26print(knee_angle) 27 28# 290 152.8° 301 35.0° 31dtype: object

投稿2022/09/17 11:54

編集2022/09/17 12:12
melian

総合スコア19761

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

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

KYuki1218

2022/09/17 12:34

実現したいことを的確に解決いただき心より感謝申し上げます!
guest

0

python

1import pandas as pd 2import numpy as np 3import io 4 5df = pd.read_csv(io.StringIO(csv_data)) 6 7def calc_knee_angle(args): 8 f, t = args 9 cos_theta = np.dot(f, t) / (np.linalg.norm(f) * np.linalg.norm(t)) 10 theta = np.arccos(cos_theta) * 180 / np.pi 11 return round(theta, 1) 12 13hip = df.filter(regex='hip').apply(np.array, axis=1) 14knee = df.filter(regex='knee').apply(np.array, axis=1) 15ankle = df.filter(regex='ankle').apply(np.array, axis=1) 16f = knee - hip 17t = ankle - knee 18knee_angle = pd.concat([f, t], axis=1).apply(calc_knee_angle, axis=1).map('{}°'.format) 19 20print(knee_angle)

投稿2023/02/06 09:02

KYuki1218

総合スコア26

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問