根据不规则图案切片

时间:2014-03-12 08:44:48

标签: python r matlab time-series

下面,您可以找到时间序列的摘录。我想切割由空白区分开的行(白色空间是为了清晰起见,数据中没有空行)。有一个重复的模式,即21倍的值X,4个不同的值ABCD,21倍的值Y,4个不同的值EFGH,21倍的值Z等。在这种情况下,我有兴趣获得BCDY,FGHZ等上。

问题是这种模式有时会因数据丢失而中断,使其不规则。结果,我想丢弃的值的数量(值X,Y,Z)有时低于21。也可能缺少2014-01-20 00:05:00和2014-01-20 00:11:00之间的值。

我可以想到循环系列,但我更喜欢矢量化方法。我想在R中实现它,但Python或Matlab也会这样做。

有什么想法吗?感谢。

2014-01-20 00:00:00    197021
2014-01-20 00:01:00    197021
2014-01-20 00:02:00    197021
2014-01-20 00:03:00    197021
2014-01-20 00:04:00    197021
2014-01-20 00:05:00    197021
2014-01-20 00:06:00    197021
2014-01-20 00:07:00    197021
2014-01-20 00:08:00    197021
2014-01-20 00:09:00    197021
2014-01-20 00:10:00    197021
2014-01-20 00:11:00    197021
2014-01-20 00:12:00    197021
2014-01-20 00:13:00    197021
2014-01-20 00:14:00    197021
2014-01-20 00:15:00    197021
2014-01-20 00:16:00    196836

2014-01-20 00:17:00    196865
2014-01-20 00:18:00    196787
2014-01-20 00:19:00    196915
2014-01-20 00:20:00    196902

2014-01-20 00:21:00    196902
2014-01-20 00:22:00    196902
2014-01-20 00:23:00    196902
2014-01-20 00:24:00    196902
2014-01-20 00:25:00    196902
2014-01-20 00:26:00    196902
2014-01-20 00:27:00    196902
2014-01-20 00:28:00    196902
2014-01-20 00:29:00    196902

2 个答案:

答案 0 :(得分:1)

如果我理解你,你想要删除上一行与上一行不变的所有数据行。在Matlab中,您可以使用diff()函数和逻辑索引来完成此操作。假设您的数据是双列矩阵,那么表达式

data([true; diff(data(:,2))~=0],:)

将返回一个两列矩阵,只有符合要求的数据。您可能需要单独检查第一行:我不清楚您的描述是否总是想要第一行。以上将始终保持它。将true更改为false以始终删除它。

编辑(响应第一条评论)

在上面的表达式中用true替换false会丢弃第一行。这将为您留下5行的块,您希望丢弃每个块中的第一行。这也可以通过逻辑索引来完成。这很简单,除了你需要防止最后一个块包含少于5行的情况:

pData = data([false; diff(data(:,2))~=0],:);
selector = repmat([false; true; true; true; true], ceil(size(pData, 1))/5, 1);
pData = pData(selector(1:size(pData,1)),:);

我希望这有帮助!

答案 1 :(得分:1)

我很尴尬地解释下面代码的逻辑,因为它对我来说很明显 如果需要任何精度,请问我。

我只是给出这样的解释:
你写了"我要丢弃的值的数量(值X,Y,Z)有时低于21。"
在我的代码中,我所做的假设是这个较低的数字不能低于3.

使用StringIO并不是一项要求,只是为了让我能够轻松地呈现代码可以运行的代码,处理代码中包含的数据。
唯一的要求是将一个iterable传递给函数slik():它可以是生成器,如下面的代码,或文件处理程序,列表或其他任何可以迭代的函数。

我拆分代码以便在不必向下滚动的情况下显示执行指令,但这两个部分必须在同一个系列中才能运行它。

text = '''
2014-01-20 00:00:00    197021
2014-01-20 00:01:00    197021
2014-01-20 00:02:00    197021
2014-01-20 00:03:00    197021
2014-01-20 00:04:00    197021
2014-01-20 00:05:00    197021
2014-01-20 00:06:00    197021
2014-01-20 00:07:00    197021
2014-01-20 00:08:00    197021
2014-01-20 00:09:00    197021
2014-01-20 00:10:00    197021
2014-01-20 00:11:00    197021
2014-01-20 00:12:00    197021
2014-01-20 00:13:00    197021
2014-01-20 00:14:00    197021
2014-01-20 00:15:00    197021
2014-01-20 00:16:00    196836
2014-01-20 00:17:00    196865
2014-01-20 00:18:00    196787
2014-01-20 00:19:00    196915
2014-01-20 00:20:00    196902
2014-01-20 00:21:00    196902
2014-01-20 00:22:00    196902
2014-01-20 00:23:00    196902
2014-01-20 00:24:00    196902
2014-01-20 00:25:00    196902
2014-01-20 00:26:00    196902
2014-01-20 00:27:00    196902
2014-01-20 00:28:00    196902
2014-01-20 00:29:00    196902
'''

from StringIO import StringIO
rid = (x.strip() for x in StringIO(text))

def slik(INPUT):
    from collections import deque
    rows = deque( ((x for x in INPUT if x).next(),)  , maxlen=10 )
    rows.extend ( INPUT.next() for i in xrange(8) )
    val  = deque( (x.rsplit(None,1)[1] for x in rows), maxlen=10)
    for x in INPUT:
        rows.append(x)
        val.append(x.rsplit(None,1)[1])
        if val[0]==val[1]==val[2] != val[7]==val[8]==val[9]:
            for i in (3,4,5,6,7):  yield rows[i]

print '\n'.join(slik(rid))