【问题标题】:Slice according to an irregular pattern根据不规则图案切片
【发布时间】:2014-04-16 06:29:18
【问题描述】:

您可以在下面找到时间序列的摘录。我想分割由空白分隔的行(空白是为了清楚起见,数据中没有空行)。有一个反复出现的模式,即 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

【问题讨论】:

  • 丢失的数据是什么样的?因为否则听起来你只想要从第 27 行开始的 25 行组(即 Matlab 中的 BCDY = data(27:27+25, :)
  • 您能方便地与我们分享您的数据吗?以下是一些关于如何做到这一点的提示:stackoverflow.com/questions/5963269/… 我打赌rle 将成为最终解决方案的一部分。
  • 为什么00:16:00 19683600:17:00 196865 之间有一个空格?我知道这个空白实际上并不存在,真正的问题是:时间序列与以下时间序列有什么区别??

标签: python r matlab time-series


【解决方案1】:

我不好意思解释以下代码的逻辑,因为它对我来说似乎很明显。
如果需要任何精度,请询问我。

我只是给出这个解释:
您写道“我想要丢弃的值的数量(值 X、Y、Z)有时低于 21。”
在我的代码中,我所做的假设是这个较低的数字不能低于 3。

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

我拆分代码是为了让执行指令不用向下滚动就可以显示出来,但是这两部分必须在同一个coe中才能运行。

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

【讨论】:

    【解决方案2】:

    如果我理解你的话,你想删除最后一列与前一行没有变化的所有数据行。在 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)),:);
    

    我希望这会有所帮助!

    【讨论】:

    • 这越来越接近,但它导致 5 个值与前面的一系列相等值不同。我也想忽略第一个更改的值。最后,我想保留第一个更改值之后的四个值。
    猜你喜欢
    • 1970-01-01
    • 2018-03-23
    • 2018-12-23
    • 2015-08-31
    • 2022-01-19
    • 2018-10-19
    • 2017-02-07
    • 2012-01-31
    • 1970-01-01
    相关资源
    最近更新 更多