前提・実現したいこと
Pandas.Dataframeで前の行の値を使って、行の値を変更したい
発生している問題・エラーメッセージ
以下のようなPandas.Dataframeのデータがあります。
各行はそのTimeの時点におけるx,y,zの位置を表しています。(Timeはmsec,xyzはmm)
Time x y z
0 0 1950.385254 -114.936646 845.404541
1 504 1950.385254 -114.936676 845.404419
2 1832 1950.385376 -114.936737 845.404541
3 1976 1950.389038 -114.934784 845.401611
4 1984 1950.414795 -114.921631 845.382813
5 1992 1950.484375 -114.885681 845.331421
6 2000 1950.619995 -114.815666 845.231262
7 2008 1950.843750 -114.700241 845.066101
8 2016 1951.177246 -114.528023 844.820007
9 2024 1951.642944 -114.287712 844.475952
10 2032 1952.261841 -113.967934 844.018433
11 2040 1953.056641 -113.557175 843.430725
12 2048 1954.048828 -113.044235 842.696533
13 2056 1955.259888 -112.417793 841.799194
14 2064 1956.711426 -111.666199 840.722046
15 2072 1958.424561 -110.778175 839.448792
16 2080 1960.421387 -109.742630 837.962463
17 2088 1962.721436 -108.547462 836.246277
18 2096 1965.346558 -107.182030 834.282959
19 2104 1968.317383 -105.634575 832.055420
20 2112 1971.652832 -103.893509 829.545898
21 2120 1975.370239 -101.949677 826.739685
これをうまいこと処理して、前の行との
時間の差分
位置の差分((x0-x1) ** 2 + (y0-y1) ** 2 + (z0-z1) ** 2 ) ** 0.5
位置の差分 / 時間の差分を求めたいです。
サンプルのソースコード
Python
1import pandas as pd 2 3def length(pos1,pos2): 4 ans = ((pos1.x - pos2.x) **2 + (pos1.y - pos2.y) **2 + (pos1.z - pos2.z) **2)** 0.5 5 return ans 6 7df = pd.read_excel('test2.xlsx') 8lastvar = 0 9df['df_time'] = 0 10df['len'] = 0.0 11df['spd'] = 0.0 12 13for item in df.itertuples(): 14 if (hasattr(lastvar, 'Time')): 15 diff = item.Time - lastvar.Time 16 len = length(item,lastvar) 17 df.at[item.Index, 'df_time'] = diff 18 df.at[item.Index, 'len'] = len 19 df.at[item.Index, 'spd'] = len / diff * 1000 20 21 lastvar = item 22print(df)
結果
Time x y z df_time len spd
0 0 1950.385254 -114.936646 845.404541 0 0.000000 0.000000
1 504 1950.385254 -114.936676 845.404419 504 0.000126 0.000249
2 1832 1950.385376 -114.936737 845.404541 1328 0.000183 0.000138
3 1976 1950.389038 -114.934784 845.401611 144 0.005080 0.035280
4 1984 1950.414795 -114.921631 845.382813 8 0.034493 4.311665
5 1992 1950.484375 -114.885681 845.331421 8 0.093675 11.709316
6 2000 1950.619995 -114.815666 845.231262 8 0.182556 22.819506
7 2008 1950.843750 -114.700241 845.066101 8 0.301110 37.638782
8 2016 1951.177246 -114.528023 844.820007 8 0.448822 56.102707
9 2024 1951.642944 -114.287712 844.475952 8 0.626895 78.361925
10 2032 1952.261841 -113.967934 844.018433 8 0.833436 104.179465
11 2040 1953.056641 -113.557175 843.430725 8 1.070435 133.804352
12 2048 1954.048828 -113.044235 842.696533 8 1.336630 167.078779
13 2056 1955.259888 -112.417793 841.799194 8 1.632272 204.034050
14 2064 1956.711426 -111.666199 840.722046 8 1.957576 244.697004
15 2072 1958.424561 -110.778175 839.448792 8 2.311838 288.979722
16 2080 1960.421387 -109.742630 837.962463 8 2.696079 337.009862
17 2088 1962.721436 -108.547462 836.246277 8 3.108689 388.586106
18 2096 1965.346558 -107.182030 834.282959 8 3.551097 443.887085
19 2104 1968.317383 -105.634575 832.055420 8 4.022729 502.841118
20 2112 1971.652832 -103.893509 829.545898 8 4.522635 565.329433
21 2120 1975.370239 -101.949677 826.739685 8 5.047022 630.877725
試したこと
添付のコードのように、For文でかけるといえばかけるのですが、なんだかしっくり来ないというか、
スマートでないですし、前の値をループで保存しているので、並列化等ができないと思っています。
このコードをスマートに書き換えていただけないでしょうか?
Python初めて2日程度なので、Pythonらしく直していただいて構いません。
改良後のソースコード
lehshellさんから改良案を頂き、そのあたりで自分で調べた結果もふまえて書き換えたコードを以下においておきます。
shiftメソッドの他に、diffでもできるみたいです。
Python
1import pandas as pd 2 3def length(pos1,pos2): 4 ans = ((pos1.x - pos2.x) **2 + (pos1.y - pos2.y) **2 + (pos1.z - pos2.z) **2)** 0.5 5 return ans 6 7def length2(diffx,diffy,diffz): 8 ans = (diffx ** 2 + diffy ** 2 + diffz ** 2) ** 0.5 9 return ans 10 11def method1(): #改良前 12 df = pd.read_excel('test2.xlsx') 13 lastvar = 0 14 df['df_time'] = 0 15 df['len'] = 0.0 16 df['spd'] = 0.0 17 18 for item in df.itertuples(): 19 if (hasattr(lastvar, 'Time')): 20 diff = item.Time - lastvar.Time 21 len = length(item,lastvar) 22 df.at[item.Index, 'df_time'] = diff 23 df.at[item.Index, 'len'] = len 24 df.at[item.Index, 'spd'] = len / diff * 1000 25 lastvar = item 26 print(df) 27 28def method2(): #改良案1 29 df = pd.read_excel('test2.xlsx') 30 df['df_time'] = (df['Time'] - df['Time'].shift(1)).fillna(0) 31 df['len'] = length(df, df.shift(1)).fillna(0) 32 df['spd'] = (df['len'] / df['df_time'] * 1000).fillna(0) 33 print(df) 34 35def method3(): #改良案2 36 df = pd.read_excel('test2.xlsx') 37 df['df_time'] = df['Time'].diff().fillna(0) 38 df['len'] = length2(df["x"].diff(),df["y"].diff(),df["z"].diff()).fillna(0) 39 df['spd'] = (df['len'] / df['df_time'] * 1000).fillna(0) 40 print(df) 41 42 43method1() 44method2() 45method3()
回答1件
あなたの回答
tips
プレビュー