python - 如何从 Python 中的两个 n 维数组中获取匹配的行?

标签 python arrays numpy

我有两个 numPy 数组,它们具有不同的行数和相同的列数。每个数组的结构 - 年、月、日、时间、number_of_satellite、value_of_data。每个数组都有不同类型的数据。

我如何比较这两个数组以仅获取两个数组中的公共(public)行,其中比较参数是前 5 列,然后是具有对应值的两列。例如:

A=[('2015', '1', '1', 0.0, 'G06', 46.29)
 ('2015', '1', '1', 0.0, 'G12', 444.344)
 ('2015', '1', '1', 0.0, 'G14', -99.269)
 ('2015', '1', '1', 0.0, 'G20', 6.874)
 ('2015', '1', '1', 0.0, 'G24', 158.488)
 ('2015', '1', '1', 0.0, 'G25', -60.831)
 ('2015', '1', '1', 0.0, 'G31', -48.234)
 ('2015', '1', '1', 0.0, 'R07', -6.243)]

B=[('2015', '1', '1', 0.0, 'G06', '0.000')
 ('2015', '1', '1', 0.0, 'G12', '0.000')
 ('2015', '1', '1', 0.0, 'G14', '0.000')
 ('2015', '1', '1', 0.0, 'G24', '0.000')
 ('2015', '1', '1', 0.0, 'G25', '0.000')
 ('2015', '1', '1', 0.0, 'G29', '0.000')
 ('2015', '1', '1', 0.0, 'G31', '0.000')]

结果,我想得到:

C=[('2015', '1', '1', 0.0, 'G06', 46.29, '0.000')
 ('2015', '1', '1', 0.0, 'G12', 444.344, '0.000')
 ('2015', '1', '1', 0.0, 'G14', -99.269, '0.000')
 ('2015', '1', '1', 0.0, 'G24', 158.488, '0.000')
 ('2015', '1', '1', 0.0, 'G25', -60.831, '0.000')
 ('2015', '1', '1', 0.0, 'G31', -48.234, '0.000')]

我可以使用循环来完成,但当您的数组行数超过 50000 时,这不是有效的解决方案。

最佳答案

numpy 代码的死水中,有一个简单的解决方案,recfunctions.join_by

import numpy as np

A=[('2015', '1', '1', 0.0, 'G06', 46.29),
 ('2015', '1', '1', 0.0, 'G12', 444.344),
 ('2015', '1', '1', 0.0, 'G14', -99.269),
 ('2015', '1', '1', 0.0, 'G20', 6.874),
 ('2015', '1', '1', 0.0, 'G24', 158.488),
 ('2015', '1', '1', 0.0, 'G25', -60.831),
 ('2015', '1', '1', 0.0, 'G31', -48.234),
 ('2015', '1', '1', 0.0, 'R07', -6.243)]

B=[('2015', '1', '1', 0.0, 'G06', '0.000'),
 ('2015', '1', '1', 0.0, 'G12', '0.000'),
 ('2015', '1', '1', 0.0, 'G14', '0.000'),
 ('2015', '1', '1', 0.0, 'G24', '0.000'),
 ('2015', '1', '1', 0.0, 'G25', '0.000'),
 ('2015', '1', '1', 0.0, 'G29', '0.000'),
 ('2015', '1', '1', 0.0, 'G31', '0.000')]

dt=[('a', 'S4'), ('b', 'S1'), ('c', 'S1'), ('d',float), ('e', 'S3'), ('f',float)]
aA=np.array(A,dt)
aB=np.array(B,dt)

flds=list('abcde')

from numpy.lib import recfunctions
mrgd = recfunctions.join_by(flds, aA, aB, usemask=False)
print(mrgd)
print(mrgd.dtype)

生产

[('2015', '1', '1', 0.0, 'G06', 46.29, 0.0)
 ('2015', '1', '1', 0.0, 'G12', 444.344, 0.0)
 ('2015', '1', '1', 0.0, 'G14', -99.269, 0.0)
 ('2015', '1', '1', 0.0, 'G24', 158.488, 0.0)
 ('2015', '1', '1', 0.0, 'G25', -60.831, 0.0)
 ('2015', '1', '1', 0.0, 'G31', -48.234, 0.0)]
[('a', 'S4'), ('b', 'S1'), ('c', 'S1'), ('d', '<f8'), ('e', 'S3'), ('f1', '<f8'), ('f2', '<f8')]

在当前组织中,recfunctions 必须单独导入。 https://stackoverflow.com/a/33680606/901925

我们必须检查代码以了解它是如何实际实现的。而且我不知道,如果没有进一步的计时,速度与等效的 pandas 相比如何。


对于这个小样本,recfunctionspandas 更快,特别是如果包括创建数据帧所需的时间。

In [302]: %%timeit 
   .....: a = pd.DataFrame(A)
   .....: b = pd.DataFrame(B)
   .....: c = pd.merge(a, b, 'inner', left_on=[0,1,2,3,4], right_on=[0,1,2,3,4]) 
   .....: 
100 loops, best of 3: 8.01 ms per loop
In [303]: %%timeit
   .....: aA=np.array(A,dt)
   .....: aB=np.array(B,dt)
   .....: aC=recfunctions.join_by(flds, aA, aB,usemask=False)
   .....: 
100 loops, best of 3: 3.35 ms per loop

与像 in1d(不尝试合并)这样的 numpy 集合操作相比,两者都很慢:

In [308]: timeit np.intersect1d(aA[flds],aB[flds])
1000 loops, best of 3: 326 µs per loop

关于python - 如何从 Python 中的两个 n 维数组中获取匹配的行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36236494/

相关文章:

python - Python 对列表中坐标对(2 元组)的高效重新排序

用于打印 n 行模式 1 121 12321 12 1 的 Python 程序

javascript - 复制要添加到同一数组的最后一个数组对象

python - matplotlib.pyplot.draw() 和 matplotlib.pyplot.show() 没有效果

python - 在shinyapps.io 上使用 python 3 in reticulate

python - Python 的 C 和 C++ 库如何跨平台?

来自 S3 的 PHP CSV 作为字符串 - 想要转换为数组

javascript - 从 URL 中获取图像 byte/base64

python - 使用 NumPy 将一个数组与另一个数组建立索引

python - 如何用单个 numpy 数组操作替换这个三重 For 循环?