使用Pandas TimeSeries编码变量

时间:2014-01-21 12:36:51

标签: python numpy pandas time-series

作为我在previous question中努力解决的问题的后续工作,我在Pandas的鼠标跟踪实验中分析了一些非常复杂的行为数据已经有很长一段时间了。

我的数据的相关子集如下所示:

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

其中,xyt是鼠标坐标和时间戳的1D 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

但是,这种方法,TimeSeries的每一行都嵌套了2 DataFrame,绝对不是惯用的(参见this question);虽然我已经能够做很多事了,但我觉得我要反对熊猫,让自己的生活变得困难。

我认为,正确的方法是将rxry存储为独立的数据结构,或者将302列添加到现有的data,每个时间步一个rxry

第一种方法的问题是我无法访问我的分类数据(即subjectstimuliresp列,其中包括我遗漏的内容在这里),第二个问题是我最终得到DataFrame数千列宽(并且对于我应用的每个转换再次更宽:每一步的速度,每一步的角度等),并且没有访问特定时间系列的有用方式(即我目前称之为data.rx.mean().plot()

所有这些只是我的问题的序言,即:

  

Pandas或任何其他python库是否提供了处理大量时间序列数据的方法,同时保留了伴随它们的编码数据?

谢谢,

约恩

1 个答案:

答案 0 :(得分:0)

如果我找到了我想在这里做的解决方案,我已经通过电子邮件询问了,所以我分享了我迄今为止所做的事情。这可能不是使用pandas的规范方式,但它对我来说已经足够了。

简而言之,我将数据拆分为几个数据框。 第一个data如上所述,但我只使用与单个值对应的列,例如trialstimuliresprt

对于我的时间序列数据,我使用了两个额外的数据帧,一个用于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]

最后,要根据x中存储的编码变量选择ydata数据的特定子集,我只需要获取相关子集的index数据

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

并使用nx方法选择nyiloc的匹配子集。

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