gpt4 book ai didi

python - numpy时间序列合并并用较早的值填充缺失值

转载 作者:太空宇宙 更新时间:2023-11-03 15:15:26 25 4
gpt4 key购买 nike

我的数据如下所示:

timedelta64 1, temp1A, temp 1B, temp1C, ...
timedelta64 2, temp2A, temp 2B, temp2C, ...

数据被摄取到两个 numpy 数组中:

  1. 一系列时间戳raw_timestamp , dtype=[('datetime', '<M8[s]')]

    '2009-01-01T18:41:00', 
    '2009-01-01T18:44:00',
    '2009-01-01T18:46:00',
    '2009-01-01T18:47:00',
  2. 传感器数据表 raw_sensor , dtype=[ ('sensorA', '<u4'), ('sensorB', '<u4'), ('sensorC', '<u4'), ('sensorD', '<u4'), ('sensorE', '<u4'), ('sensorF', '<u4'), ('sensorG', '<u4'), ('sensorH', '<u4'), ('signal', '<u4')]

     (755, 855, 755, 855, 743, 843, 743, 843, 2),
    (693, 793, 693, 793, 693, 793, 693, 793, 1),
    (755, 855, 755, 855, 743, 843, 743, 843, 2),
    (693, 793, 693, 793, 693, 793, 693, 793, 1),

我生成了一个新的filled_timestamp并在每个时间步的每一行填充时间戳:filled_timestamp = np.arange(np.datetime64(starttime), np.datetime64(endtime), np.timedelta64(interval))

使用idxs = np.in1d(filled_timestamp,raw_timestamp) ,我有 filled 的所有索引与raw的时间戳相匹配。所以我可以分配 filled_sensorraw_sensor 中的匹配数据

filled_sensor[idxs] = raw_sensor

Q1。有没有更好/更快的方法来交叉这些?

现在filled数组看起来像:

>>> filled_timestamp, filled_sensor # shown side-by-side for convenience 
array([
1 # ('2009-01-01T18:41:00') (755, 855, 755, 855, 743, 843, 743, 843, 2),
2 # ('2009-01-01T18:42:00') (0, 0, 0, 0, 0, 0, 0, 0, 0),
3 # ('2009-01-01T18:43:00') (0, 0, 0, 0, 0, 0, 0, 0, 0),
4 # ('2009-01-01T18:44:00') (693, 793, 693, 793, 693, 793, 693, 793, 1),
5 # ('2009-01-01T18:45:00') (0, 0, 0, 0, 0, 0, 0, 0, 0),
6 # ('2009-01-01T18:46:00') (693, 793, 693, 793, 693, 793, 693, 793, 1),
7 # ('2009-01-01T18:47:00') (693, 793, 693, 793, 693, 793, 693, 793, 1)
],
dtype=[('datetime', '<M8[s]')], [('sensorA', '<u4'), ('sensorB', '<u4'), ('sensorC', '<u4'), ('sensorD', '<u4'), ('sensorE', '<u4'), ('sensorF', '<u4'), ('sensorG', '<u4'), ('sensorH', '<u4'), ('signal', '<u4')]

第二季度。如何使用前一个非空行中的值填充缺失的行?除了列(0 和 3 以及最后一列)外,填充值为 0

在我上面的例子中:

第 2 行和第 3 行将从第 1 行获取值,

第 5 行将从第 4 行获取值

最终结果:

>>> filled_timestamp, filled_sensor # shown side-by-side for convenience 
array([
1 # ('2009-01-01T18:41:00') (755, 855, 755, 855, 743, 843, 743, 843, 2),
2 # ('2009-01-01T18:42:00') (0, 855, 755, 0, 743, 843, 743, 843, 0),
3 # ('2009-01-01T18:43:00') (0, 855, 755, 0, 743, 843, 743, 843, 0),
4 # ('2009-01-01T18:44:00') (693, 793, 693, 793, 693, 793, 693, 793, 1),
5 # ('2009-01-01T18:45:00') (0, 793, 693, 0, 693, 793, 693, 793, 0),
6 # ('2009-01-01T18:46:00') (693, 793, 693, 793, 693, 793, 693, 793, 1),
7 # ('2009-01-01T18:47:00') (693, 793, 693, 793, 693, 793, 693, 793, 1)
],
dtype=[('datetime', '<M8[s]')], [('sensorA', '<u4'), ('sensorB', '<u4'), ('sensorC', '<u4'), ('sensorD', '<u4'), ('sensorE', '<u4'), ('sensorF', '<u4'), ('sensorG', '<u4'), ('sensorH', '<u4'), ('signal', '<u4')]

最佳答案

交叉路口

快速交叉路口的最佳选择可能是 np.searchsorted 。它将在 filled_timestamp 中进行二分搜索对于 raw_timestamp 的元素:

idx = np.searchsorted(filled_timestamp, raw_timestamp)

仅当 raw_timestamp 的每个元素都正确时,这才是准确的实际上发生在 filled_timestamp因为np.searchsorted无论如何都会返回插入索引。

非矢量化解决方案

您想要设置 filled_sensor 的切片来自idx[n]idx[n + 1]值为 raw_sensor[n] :

from itertools import zip_longest
for start, end, row in zip_longest(idx, idx[1:], raw_sensor):
filled_sensor[start:end] = row

我正在使用zip_longest这里最后一个值来自 idx[1:]将是None ,使最后一个切片等于 filled_sensor[idx[-1]:]无需特殊条件。

矢量化解决方案

您可以创建filled_sensor直接来自raw_sensor如果您知道要重复 raw_sensor 中的哪些索引。您可以通过申请 np.cumsum 获取该信息至idx转换为 bool 数组:

idx_mask = np.zeros(filled_timestamp.shape, np.bool)
idx_mask[idx] = True

基本上,我们从一个与 filled_timestamp 大小相同的 bool 数组开始即True (1) 无论来自 raw_timestamp 的条目火柴。我们可以将其转换为 raw_timestamp 中的索引通过计算到目前为止发生的总匹配数:

indexes = np.cumsum(idx_mask) - 1

请记住 indexes是整数数组,而不是 bool 值。每当找到新的匹配项时,它就会增加。 - 1从计数转换为索引,因为第一个匹配项的计数为 1 而不是 0。

现在你可以制作filled_sensor :

filled_sensor = raw_sensor[indexes]

这里唯一可能的警告是 if filled_sensor[0]不是来自 raw_sensor[0] 。然后它将被替换为 raw_sensor[-1] 。鉴于您如何在 filled 中构建时间基于raw ,我不确定是否会成为一个问题。

示例

以下是交集矢量化解决方案步骤的示例,其中包含您在问题中显示的数据。

我们从

开始
raw_timestamp = np.array(['2009-01-01T18:41:00', 
'2009-01-01T18:44:00',
'2009-01-01T18:46:00',
'2009-01-01T18:47:00',], dtype='datetime64[s]')
raw_sensor = np.array([(755, 855, 755, 855, 743, 843, 743, 843, 2),
(693, 793, 693, 793, 693, 793, 693, 793, 1),
(755, 855, 755, 855, 743, 843, 743, 843, 2),
(693, 793, 693, 793, 693, 793, 693, 793, 1),],
dtype=[('sensorA', '<u4'), ('sensorB', '<u4'),
('sensorC', '<u4'), ('sensorD', '<u4'),
('sensorE', '<u4'), ('sensorF', '<u4'),
('sensorG', '<u4'), ('sensorH', '<u4'),
('signal', '<u4')])

我们可以生成filled_timestamp作为

filled_timestamp = np.arange('2009-01-01T18:41:00',
'2009-01-01T18:48:00', 60, dtype='datetime64[s]')

其产量如预期:

array(['2009-01-01T18:41:00', '2009-01-01T18:42:00', '2009-01-01T18:43:00',
'2009-01-01T18:44:00', '2009-01-01T18:45:00', '2009-01-01T18:46:00',
'2009-01-01T18:47:00'], dtype='datetime64[s]')

我对 dtypes 有一点随意。通过将时间戳设为普通数组而不是结构化数组,但我认为这对您的目的没有什么影响。

  1. idx = np.searchsorted(filled_timestamp, raw_timestamp)产量

    idx = np.array([0, 3, 5, 6], dtype=np.int)

    这意味着索引 0, 3, 5, 6filled_timestamp匹配 raw_timestamp 中的值.

  2. idx_mask然后变成

    idx_mask = np.array([True, False, False, True, False, True, True], dtype=np.bool)

    这基本上与idx同义。 ,除了扩展为与 filled_timestamp 大小相同的 bool 掩码.

  3. 现在是棘手的部分:indexes = np.cumsum(idx_mask) - 1 :

    indexes = array([0, 0, 0, 1, 1, 2, 3], dtype=np.int)

    这可以解释如下:filled_sensor[0:3]应该来自raw_sensor[0]filled_sensor[3:5]应该来自raw_sensor[1] , filled_sensor[5]应该来自raw_sensor[2] , filled_sensor[6]应该来自raw_sensor[3] .

  4. 所以现在我们使用 indexes直接提取 raw_sensor 的正确元素使用filled_sensor = raw_sensor[indexes] :

    np.array([(755, 855, 755, 855, 743, 843, 743, 843, 2),
    (755, 855, 755, 855, 743, 843, 743, 843, 2),
    (755, 855, 755, 855, 743, 843, 743, 843, 2),
    (693, 793, 693, 793, 693, 793, 693, 793, 1),
    (693, 793, 693, 793, 693, 793, 693, 793, 1),
    (755, 855, 755, 855, 743, 843, 743, 843, 2),
    (693, 793, 693, 793, 693, 793, 693, 793, 1)],
    dtype=[('sensorA', '<u4'), ('sensorB', '<u4'),
    ('sensorC', '<u4'), ('sensorD', '<u4'),
    ('sensorE', '<u4'), ('sensorF', '<u4'),
    ('sensorG', '<u4'), ('sensorH', '<u4'),
    ('signal', '<u4')])

关于python - numpy时间序列合并并用较早的值填充缺失值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43924459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com