我有两个numPy数组,它们具有不同的行数和相同的列数。每个数组的结构 - 年,月,日,时间,number_of_satellite,value_of_data。每个数组都有不同类型的数据。
如何比较这两个数组以仅获取两个数组中的常见行,其中比较参数是前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+时,它不是有效的解决方案。
答案 0 :(得分:3)
在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
的比较。
使用此小样本,recfunctions
比pandas
快,特别是如果包含创建数据帧所需的时间。
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 set操作相比,两者都很慢(不会尝试合并):
In [308]: timeit np.intersect1d(aA[flds],aB[flds])
1000 loops, best of 3: 326 µs per loop
答案 1 :(得分:2)
为此使用pandas:
import pandas as pd
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])
其中'inner'
表示仅在两个数组中都存在键值时进行合并。 left_on=[0,1,2,3,4]
表示将这些列用作键值。
它给出了以下结果:
In: print(c)
Out:
0 1 2 3 4 5_x 5_y
0 2015 1 1 0 G06 46.290 0.000
1 2015 1 1 0 G12 444.344 0.000
2 2015 1 1 0 G14 -99.269 0.000
3 2015 1 1 0 G24 158.488 0.000
4 2015 1 1 0 G25 -60.831 0.000
5 2015 1 1 0 G31 -48.234 0.000