python - 基于第一行合并多维 NumPy 数组

标签 python arrays numpy

我必须处理传感器数据(特别是来自 ros,但它不应该是相关的)。为此,我有几个二维 numpy 数组,其中一行存储时间戳,其他一行存储相应的传感器数据。问题是,这样的数组没有相同的维度(不同的采样时间)。我需要将所有这些数组合并成一个大数组。我如何根据时间戳执行此操作,比如说,用 0 或 NaN 替换缺失的数字?

我的情况示例:

import numpy as np

time1=np.arange(1,10)
data1=np.random.randint(200, size=time1.shape)

a=np.array((time1,data1))
print(a)

time2=np.arange(1,10,2)
data2=np.random.randint(200, size=time2.shape)

b=np.array((time2,data2))

print(b)

返回输出

[[  1   2   3   4   5   6   7   8   9]
 [ 51   9 117 174 164  60  95 197  30]]

[[  1   3   5   7   9]
 [ 35 188 114 153  36]]

我要找的是

[[  1   2   3   4   5   6   7   8   9]
 [ 51   9 117 174 164  60  95 197  30]
 [ 35   0 188   0 114   0 153   0  36]]

有什么方法可以有效地实现这一点?这是一个例子,但我正在处理数以千计的样本。谢谢!

最佳答案

对于一个 b 矩阵的简单情况

a 的第一行存储所有可能的时间戳,并且 ab 的第一行都被排序,我们可以使用 np.searchsorted -

idx = np.searchsorted(a[0],b[0])
out_dtype = np.result_type((a.dtype,b.dtype))
b0 = np.zeros(a.shape[1],dtype=out_dtype)
b0[idx] = b[1]
out = np.vstack((a,b0))

对于几个b-矩阵

方法 #1

要扩展到多个 b-矩阵,我们可以在循环中使用 np.searchsorted 遵循类似的方法,就像这样 -

def merge_arrays(a, B):
    # a : Array with first row holding all possible timestamps
    # B : list or tuple of all b-matrices
    
    lens = np.array([len(i) for i in B])
    L = (lens-1).sum() + len(a)
    out_dtype = np.result_type(*[i.dtype for i in B])
    out = np.zeros((L, a.shape[1]), dtype=out_dtype)
    out[:len(a)] = a
    s = len(a)
    for b_i in B:
        idx = np.searchsorted(a[0],b_i[0])
        out[s:s+len(b_i)-1,idx] = b_i[1:]
        s += len(b_i)-1
    return out

sample 运行-

In [175]: a
Out[175]: 
array([[ 4, 11, 16, 22, 34, 56, 67, 87, 91, 99],
       [ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10]])

In [176]: b0
Out[176]: 
array([[16, 22, 34, 56, 67, 91],
       [20, 80, 69, 79, 47, 64],
       [82, 88, 49, 29, 19, 19]])

In [177]: b1
Out[177]: 
array([[ 4, 16, 34, 99],
       [28, 34,  0,  0],
       [36, 53,  5, 38],
       [17, 79,  4, 42]])

In [178]: merge_arrays(a, [b0,b1])
Out[178]: 
array([[ 4, 11, 16, 22, 34, 56, 67, 87, 91, 99],
       [ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10],
       [ 0,  0, 20, 80, 69, 79, 47,  0, 64,  0],
       [ 0,  0, 82, 88, 49, 29, 19,  0, 19,  0],
       [28,  0, 34,  0,  0,  0,  0,  0,  0,  0],
       [36,  0, 53,  0,  5,  0,  0,  0,  0, 38],
       [17,  0, 79,  0,  4,  0,  0,  0,  0, 42]])

方法 #2

如果使用 np.searchsorted 循环似乎是瓶颈,我们可以对该部分进行矢量化 -

def merge_arrays_v2(a, B):
    # a : Array with first row holding all possible timestamps
    # B : list or tuple of all b-matrices
    
    lens = np.array([len(i) for i in B])
    L = (lens-1).sum() + len(a)
    out_dtype = np.result_type(*[i.dtype for i in B])
    out = np.zeros((L, a.shape[1]), dtype=out_dtype)
    out[:len(a)] = a
    s = len(a)
    
    r0 = [i[0] for i in B]
    r0s = np.concatenate((r0))
    idxs = np.searchsorted(a[0],r0s)
    
    cols = np.array([i.shape[1] for i in B])
    sp = np.r_[0,cols.cumsum()]
    start,stop = sp[:-1],sp[1:]
    for (b_i,s0,s1) in zip(B,start,stop):
        idx = idxs[s0:s1]
        out[s:s+len(b_i)-1,idx] = b_i[1:]
        s += len(b_i)-1
    return out

关于python - 基于第一行合并多维 NumPy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56223059/

相关文章:

python - 在 Linux 中构建可移植的 Tesseract OCR 库

python - Matlibplot 阶跃函数索引 0

python - 高效处理 Python 列表中的重复项

c++ - 代码中的溢出会覆盖什么内存

javascript - 如何使用另一个对象的值过滤对象数组?

Javascript - 如何快速构造不同正整数数组的二进制表示

python - 将 numpy 解决方案转换为 dask(numpy 索引在 dask 中不起作用)

python - 具有多个列表的列表理解中的 If 语句

python - 如何从 slack api 附件获取操作结果

python - 如何暂停 Python 脚本并让用户在 Linux 终端中输入