4

データのプログラミング パターンと DataFrame の使用についてアドバイスが必要です。粒子追跡実験の結果である数千の小さな ASCII ファイルがあります (詳細については、www.openptv.net を参照してください)。各ファイルは、その時点で識別および追跡された粒子のリストです。ファイルの名前はフレームの番号です。例えば:

ptv_is.10000 (フレーム番号 10000)

prev next   x    y   z   
-1    5     0.0  0.0 0.0 
0     0     1.0 1.0 1.0  
1     1      2.0  2.0 2.0 
2     2      3.0  3.0 3.0 
3    -2      4.0  4.0 4.0 

ptv_is.10001 (ienext 時間枠、10001)

1    2      1.1 1.0 1.0 
2    8      2.0  2.0 2.0 
3    14       3.0  3.0 3.0 
4   -2       4.0  4.0 4.0 
-1   3      1.5  1.12  1.32 
0   -2      0.0   0.0 0.0 

ASCII ファイルの列は次のとおりです。prev - 前のフレームの粒子の行番号、next は次のフレームの粒子の行番号、x、y、z は粒子の座標です。「prev」の行インデックスが -1 の場合 - パーティクルは現在のフレームに表示され、時間内に戻るリンクがありません。'next' が -2 の場合、粒子には時間的に前方へのリンクがなく、軌道はこのフレームで終了します。

したがって、これらのファイルを同じ列ヘッダーを持つ単一の DataFrame に読み込み、時間のインデックス、つまりフレーム番号を追加します。

prev next   x    y   z   time
-1    5     0.0  0.0 0.0 10000
0     0     1.0 1.0 1.0  10000
1     1      2.0  2.0 2.0 10000
2     2      3.0  3.0 3.0 10000
3    -2      4.0  4.0 4.0 10000

1    2      1.1 1.0 1.0 10001 
2    8      2.0  2.0 2.0 10001
3    14       3.0  3.0 3.0 10001
4   -2       4.0  4.0 4.0 10001
-1   3      1.5  1.12  1.32 10001
0   -2      0.0   0.0 0.0 10001

ここで、DataFrame を使用する最善の方法を見つけるのが難しいと感じました。trajectory_id と呼ばれる追加の列を追加できれば、後でこの DataFrame を時間 (単一の時間インスタンスで粒子のサブグループを作成し、それらの空間分布を学習) で再インデックス化するか、trajectory_id で再インデックス化してから軌跡を作成できます。 (またはリンクされた粒子と、同じtrajectory_idのx(t)、y(t)、z(t)など、空間での時間発展について学びます)。

入力が次の場合:

prev next   x    y   z   time
-1    5     0.0  0.0 0.0 10000
0     0     1.0 1.0 1.0  10000
1     1      2.0  2.0 2.0 10000
2     2      3.0  3.0 3.0 10000
3    -2      4.0  4.0 4.0 10000

1    2      1.1 1.0 1.0 10001 
2    8      2.0  2.0 2.0 10001
3    14     3.0  3.0 3.0 10001
4   -2      4.0  4.0 4.0 10001
-1   3      1.5  1.12  1.32 10001
0   -2      0.0   0.0 0.0 10001

次に、必要な結果は次のとおりです。

prev next   x    y   z   time   trajectory_id
-1    5     0.0  0.0 0.0 10000   1
0     0     1.0 1.0 1.0  10000   2
1     1     2.0  2.0 2.0 10000   3
2     2     3.0  3.0 3.0 10000   4
3    -2     4.0  4.0 4.0 10000  -999 

1    2      1.1 1.0 1.0 10001    2
2    8      2.0  2.0 2.0 10001   3
3    14     3.0  3.0 3.0 10001   4
-1   -2     4.0  4.0 4.0 10001   -999     
-1   3      1.5  1.1  1.3 10001  5
0   -2      0.0   0.0 0.0 10001   1

つまり:

prev next    x    y   z   time   trajectory_id
-1  5       0.0  0.0  0.0    10000  1      < - appeared first time, new id
0   0       1.0  1.0  1.0    10000  2      < - the same
1   1       2.0  2.0  2.0    10000  3    <- the same
2   2       3.0  3.0  3.0    10000  4       <- the same
3  -2       4.0  4.0  4.0    10000  -999   <-  sort of NaN, there is no link in the next frame

1    2      1.1 1.0 1.0   10001  2 <- from row #1 in the time 10000, has an id = 2
2    8      2.0  2.0 2.0  10001  3 <- row #2 at previous time, has an id = 3
3    14     3.0  3.0 3.0  10001  4 < from row # 3, next on the row #14, id = 4
-1   -2     4.0  4.0 4.0  10001  -999  <- but linked, marked as NaN or -999     
-1   3      1.5  1.1  1.3 10001  5  <- new particle, new id = 5 (new trajectory_id)
0   -2      0.0   0.0 0.0 10001  1   <- from row #0  id = 1

これが私が探しているものをよりよく説明することを願っています。唯一の問題は、DataFrame テーブルの行をローリングして、新しいインデックス列 trajectory_id を作成する方法がわからないことです。

たとえば、リストを使用した単純なアプリケーションを次に示します。

http://nbviewer.ipython.org/7020209

パンダの使用に関するすべてのヒントをありがとう、アレックス

4

2 に答える 2

1

きちんとした!この問題は私の心に近いものです。また、パーティクル トラッキングにも pandas を使用しています。これは私が取り組んでいる問題とまったく同じではありませんが、ここにいくつかの役立つ pandas イディオムを提供するテストされていないスケッチがあります。

results = []
first_loop = True
next_id = None
for frame_no, frame in pd.concat(list_of_dataframes).groupby('time'):
    if first_loop:
        frame['traj_id'] = np.arange(len(frame))
        results.append(frame)
        next_id = len(frame)
        first_loop = False
        continue
    prev_frame = results[-1]
    has_matches = frame['prev'] > 0  # boolean indexer
    frame[has_matches]['traj_'id'] = prev_frame.iloc[frame[has_matches]['prev']]
    count_unmatched = (~has_matches).sum()
    frame[~has_matches]['traj_'id'] = np.arange(next_id, next_id + count_unmatched)
    next_id += count_unmatched
    results.append(frame)
pd.concat(results)
于 2013-10-17T13:41:38.363 に答える