繁体   English   中英

2D Numpy 数组:基于标准列使用另一个数组快速更新行

[英]2D Numpy array: very fast update of rows with another array based on criteria column

假设我有一个 2D Numpy 数组A ,我想根据 id 列作为标准,用另一个数组B更新特定行。

问题是我需要以非常快速的方式实现它,我首先尝试使用 Pandas 来做到这一点。 但性能不够好。 数组 A 大约有 10000 行,我需要每秒处理 100 到 500 次这样的更新。

是否可以使用普通的 Numpy 来实现? 还是我需要使用 Numba 或 Cython?

A = np.array([
   [1000001,'Peter',11],
   [1000002,'Bob',22],
   [1000003,'Julie',33],
   [1000004,'Larry',44],
   ...
])

B = [
   [1000002,'Bob',77],
   [1000004,'Mia',88],
]

A的结果应如下所示:

[
   [1000001,'Peter',11],
   [1000002,'Bob',77],
   [1000003,'Julie',33],
   [1000004,'Mia',88],
   ...
]

更新:

经过几次尝试,我发现了一个运行良好的 Numpy 解决方案:

def update_array(A, B):
    A[np.where(np.isin(A[:,0], B[:,0]))] = B
    return A

Numpy 中是否有更快的方法? 或者有人知道如何使用 Numba 进行这项工作吗? 当我刚刚放置 @jit 装饰器时,我收到一条错误消息。


更新 2

来自 Websocket 连接的原始数据流并实际到达 dict 的格式列表。

A = [ 
   {'id': 1000001, 'name': 'Peter', 'points': 11}, 
   {'id': 1000002, 'name': 'Bob', 'points': 22}, 
   {'id': 1000003, 'name': 'Julie', 'points': 33}, 
   {'id': 1000004, 'name': 'Larry', 'points': 44}, 
   ... 
]

B = [ 
   {'id': 1000002, 'name': 'Bob', 'points': 77}, 
   {'id': 1000004, 'name': 'Mia', 'points': 88},
] 

At first I thought it's faster to convert the data into a Pandas DataFrame or a Numpy Array for further processing, but now I have the impression that converting each data package takes more time than the actual data processing.


更新 3

在尝试了几种方法之后,我使用了一个以 id 作为键的“dict of dict”结构。 使用列表推导,原始结构的转换非常快。 这意味着所有进一步的数据处理现在也严重依赖于列表理解,在我看来这不是最易读的代码。 特别是因为在我的情况下,我处理的 dicts 并不总是具有相同的深度,这会产生更多的列表理解。 男孩,我今天真的很疯狂...... Pandas 在这方面要好得多,但我无法在那里获得性能。 现在使用这种 dict 方法,我觉得这不是最优雅的方式......但至少我每秒可以处理大约 20.000 dict 更新,这是一个很大的改进!

A = { 
   1000001: {'name': 'Peter', 'points': 11}, 
   1000002: {'name': 'Bob', 'points': 22}, 
   1000003: {'name': 'Julie', 'points': 33}, 
   1000004: {'name': 'Larry', 'points': 44}, 
   ... 
}

B = { 
   1000002, {'name': 'Bob', 'points': 77}, 
   1000004, {'name': 'Mia', 'points': 88},
} 

瓶颈仍然是我对数据所做的计算。 在那里我只能达到每秒 100 次左右,这就是为什么我决定不实时进行这些计算,而是按预定的时间间隔进行计算。 我仍然想了解 go 与其他方法能走多远,令人印象深刻的是普通 python 方法之间的性能差异有多大。 更不用说 Numba 或 Cython ......如果有人有进一步的想法,我很乐意了解更多!

这是仅使用 Python 的简单方法:

A = {
    1000001: ('Peter', 11),
    1000002: ('Bob', 22),
    1000003: ('Julie', 33),
    1000004: ('Larry', 44),
}

B = {
    1000002: ('Bob', 77),
    1000004: ('Mia', 88),
}

A.update(B)

那么 A 是:

{
    1000001: ('Peter', 11),
    1000002: ('Bob', 77),
    1000003: ('Julie', 33),
    1000004: ('Mia', 88)
}

我的笔记本电脑每秒可以执行大约 400 万次A.update(B)


这是一个 Pandas 解决方案,但在小样本数据上,它的速度要慢 1000 倍:

dfA = pd.DataFrame(A)
dfB = pd.DataFrame(B)

dfA[0] = dfA[0].astype(int)
dfB[0] = dfB[0].astype(int)

dfA.set_index(0, inplace=True)
dfB.set_index(0, inplace=True)

dfA.update(dfB)

现在 dfA 是:

             1   2
0                 
1000001  Peter  11
1000002    Bob  77
1000003  Julie  33
1000004    Mia  88

以下是使用 Numpy 更新的方法(Numba 应该同样工作):

A[np.isin(A[:,0],B[:,0])]=B

output:

[['1000001' 'Peter' '11']
 ['1000002' 'Bob' '77']
 ['1000003' 'Julie' '33']
 ['1000004' 'Mia' '88']]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM