2014-01-21 79 views
0

作爲我在previous question中苦苦掙扎的後續工作,我一直在努力分析Pandas中鼠標跟蹤實驗的一些非常複雜的行爲數據。使用熊貓TimeSeries編碼變量

我的數據的相關子集是這樣的:

data.iloc[0] 

time_stamp          21/11/2013 13:06 
subject             1276270 
trial               0 
stimuli              14 
resp               2 
rt               1145 
x    [-0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.... 
y    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... 
t    [1, 26, 26, 35, 45, 55, 65, 75, 85, 95, 105, 1... 
Name: 0, dtype: object 

其中,xy,並且t是鼠標座標和時間戳的一維數組numpy的。

我想用Pandas相當多的時間序列數據資源來轉換和分析這些座標爲TimeSeries的對象。我沒有問題將它們轉換爲TimeSeries對象(rxry,每個具有通過內插時間戳生成的索引爲20個毫秒間隔。

data.rx.iloc[0] 

0  -0 
20  0 
40  0 
60  0 
80  0 
100 0 
120 0 
140 0 
160 0 
180 0 
200 0 
220 0 
240 0 
260 0 
280 0 
... 
2720 1 
2740 1 
2760 1 
2780 1 
2800 1 
2820 1 
2840 1 
2860 1 
2880 1 
2900 1 
2920 1 
2940 1 
2960 1 
2980 1 
3000 1 
Length: 151, dtype: float64 

然而,這種方法,將具有2 TimeSeries嵌套在DataFrame的每一行,絕對不是慣用的(見this question);儘管我已經能夠做到這一點,但我覺得我要對付熊貓,並且讓自己難過

我認爲正確的做法,將要麼將rxry存儲爲獨立或將302列添加到我現有的data中,每個時間步一個rxry

與第一種方法的問題是,我沒有辦法訪問我的分類數據(即subjectstimuli,並且resp列,除其他外,我離開這裏了),而與第二的問題是,我最終得到了數以千計的列寬(對於每次應用的每次轉換,每一步都有速度,每一步的角度等等),並且沒有訪問特定時間系列的有用方式(即我目前的工作情況作爲調用data.rx.mean().plot()

所有這一切都是真的只是序言我的問題,這是這樣的:

Pandas或任何其他Python庫是否提供了一種處理大量時間序列數據的方法,同時保留了伴隨它們的編碼數據?

感謝,

約恩

回答

0

我已經通過電子郵件問我是否曾經發現了一個解決方案,我想在這裏做,所以我分享我一直在做什麼至今。這可能不是使用pandas的規範方式,但它對我來說是足夠的。

總之,我已將我的數據分成幾個數據幀。 第一個,data與上面一樣,但我只使用對應於單個值的列,如trial,stimuli,resprt

對於我的時間序列數據,我使用了兩個額外的數據幀,一個用於x座標數據,另一個用於y。雖然可能有更優雅的方式來生成這些,但我的代碼會執行以下操作。

data.iloc[0] 

    time_stamp          21/11/2013 13:06 
    subject             1276270 
    trial               0 
    stimuli              14 
    resp               2 
    rt               1145 
    x    [-0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.... 
    y    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ... 
    t    [1, 26, 26, 35, 45, 55, 65, 75, 85, 95, 105, 1... 
    Name: 0, dtype: object 

data['nx'], data['ny'] = zip(* 
    [even_time_steps(x, y, t) 
    for x, y, t, in zip(data.x, data.y, data.t)]) 
    # Using function even_time_steps from package squeak 
    # https://github.com/EoinTravers/Squeak 
    # Simpler applications could use 
    # data['nx'] = [pd.TimeSeries(x) for y in data['x']] 
    # data['ny'] = [pd.TimeSeries(x) for y in data['y']] 

# Seperate DataFrames 
nx = pd.concat(list(data.nx), axis=1).T 
ny = pd.concat(list(data.ny), axis=1).T 

# Remove redundant columns 
redundant = ['nx', 'ny', 'x', 'y'] # etc... 
data = data.drop(redundant, axis=1) 

# Important - reindex data 
data.index = range(len(data)) # 0, 1, 2, ..., len(data) 

現在data包含了我所有的編碼信息,nx我所有的x座標信息,並ny我y座標信息。

nx.head() 

     0 1 2 3 4 5 6 7 8  9  ...   91 
    0 0 0 0 0 0 0 0 0 0 0.00000 ...  0.953960 
    1 0 0 0 0 0 0 0 0 0 0.00099 ...  1.000000 
    2 0 0 0 0 0 0 0 0 0 0.00000 ...  1.010000 
    3 0 0 0 0 0 0 0 0 0 0.00000 ...  0.870396 
    4 0 0 0 0 0 0 0 0 0 0.00000 ...  1.000000 

      92  93  94  95  96 97 98 99 100 
    0 0.993564 1.000000 1.000000 1.00000 1.000000 1 1 1 1 
    1 1.000000 1.000000 1.000000 1.00000 1.000000 1 1 1 1 
    2 1.010000 1.008812 1.003960 1.00000 1.000000 1 1 1 1 
    3 0.906238 0.936931 0.973564 0.98604 0.993366 1 1 1 1 
    4 1.000000 1.000000 1.000000 1.00000 1.000000 1 1 1 1 

    [5 rows x 101 columns] 

最後,選擇xy數據的特定子集,根據存儲在data編碼變量,我只是把數據

subject1_index = data[data.subject==1].index 
print subject1_index 

    Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 
    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 
    36, 37, 38, 39], dtype='int64') 

的相關子集的index並選擇一個匹配子集nxny使用iloc方法。

sub1_x = nx.iloc[subject1_index] 
sub1_y = ny.iloc[subject1_index] 
for i in subject1_index: 
    plt.plot(nx.iloc[i], ny.iloc[i], 'r', alpha=.3) 
plt.plot(sub1_x.mean(), sub1_y.mean(), 'r', linewidth=2) 

enter image description here


編輯:爲了完整起見,請注意我的很多分析需要較長的 格式的數據(以及R中進行)。再一次,可能會有更優雅的 這樣做(,所以使用您自己的風險!),但我的代碼(注意,這是真實的代碼,從不同的數據集, ,我沒有打擾更改變量名稱以匹配原始示例):

# Long format data 
wide_data = data.copy() 
steps = nx.columns 
for i in steps: 
    wide_data['nx_%i' % i] = nx[i] 
    wide_data['ny_%i' % i] = ny[i] 

id_vars = ['subject_nr', 'condition', 'count_trial_sequence', 
    'trial_id', 'choice', 'accuracy'] 

# Long data with 'nx' as the variable 
long_data = pd.melt(wide_data, id_vars=id_vars, value_vars = ['nx_%i' % i for i in steps]) 
long_data['step'] = long_data.variable.map(lambda s: int(s[3:])) 
long_data['nx'] = long_data.value 

# Same with 'ny' 
tmp_long = pd.melt(wide_data, id_vars=id_vars, value_vars = ['ny_%i' % i for i in steps]) 
# Combine in single data frame 
long_data['ny'] = tmp_long['value'] 
del tmp_long 

long_data = long_data.drop(['variable', 'value'], axis=1) 
long_data.to_csv(os.path.join('data', 'long_data.csv')) 

long_data.head() 
Out[41]: 
     subject_nr  condition count_trial_sequence trial_id choice accuracy 
    0 505250022    A      0  13 rsp1  True 
    1 505250022    A      1  16 rsp1  True 
    2 505250022    B      2   2 rsp2 False 
    3 505250022    B      3   0 rsp1 False 
    4 505250022    C      4  33 rsp2 False 

     step nx ny 
    0  0 0 0 
    1  0 0 0 
    2  0 0 0 
    3  0 0 0 
    4  0 0 0