2013-10-17 49 views
4

我需要關於編程模式和DataFrame用於我們數據的建議。我們有數以千計的小型ASCII文件是粒子追蹤實驗的結果(詳情請參閱www.openptv.net)。每個文件都是該時間實例中標識和跟蹤的粒子列表。該文件的名稱是該幀的編號。例如:用於滾動窗口索引的Pandas編程模型

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 - 粒子出現在當前幀中並且沒有及時鏈接回去。如果「下一個」是-2,那麼粒子沒有及時向前的鏈接,並且軌跡在該幀中結束。

所以我們正在閱讀這些文件與同一列標題一個數據幀加上我們添加的時間索引,即幀數

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

感謝對大熊貓利用每一個暗示, 亞歷

回答

1

整潔!這個問題很接近我的心;我也使用pandas for particle tracking。這與我所處理的問題不完全相同,但這裏有一個未經測試的草圖,提供了一些有用的熊貓成語。

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) 
0

如果我理解的很好,你想跟蹤空間粒子在空間中的位置。您正在處理五個維度的數據,因此可能DataFrame不是您問題的最佳結構,您可能會考慮面板結構或減少數據。

以一個粒子,你有兩個posibilities,先治,所以你需要三個場還是把它們作爲一個整體,一個元組或例如點對象的座標爲三個不同的值。 在第一種情況下,你有時間加上三個值,所以你有四個軸,您需要一個數據幀。在第二種情況下,你有兩個軸,所以你可以使用一個系列。

對於多粒子只用一個particle_id並把所有的DataFrames一個小組或系列的數據幀英寸

一旦你知道用什麼樣的數據結構,那麼它的時間把數據的採集。

sequentialy查看這兩個文件,使「活」的粒子,例:

{particle_id1: { time1: (x1,y1,z1), time2: (x2,y2,z2), ...}, ...} 

當集合檢測到新粒子(prev爲-1)​​分配新的particle_id並放到集合上。當一個粒子「deads」蹦出來的收集,並把數據放到一個系列,然後這個系列添加到一個粒子數據幀(或數據幀/面板)。

你也可以將顆粒id和下一個字段的索引,以幫助識別IDS:

{ next_position_of_last_file: particle_id, ... } 

{ position_in_last_file: particle_id, ...}