给定两个有3列的数据集,提取两个数据集中第三列值几乎相等的行

2024-09-23 16:20:24 发布

您现在位置:Python中文网/ 问答频道 /正文

给定这两个数据集:

data_set_1.txthttps://pastebin.com/VQrsv8kU

data_set_2.txthttps://pastebin.com/jFBa6kZq

(无需注册即可下载)

我试图获得x_1y_1x_2y_2的值,其中:

z_1 = z_2(在阈值内)。你知道吗

有办法吗?你知道吗

1)两个数据集的长度不同

2)由于z_1z_2永远不会完全相等,我尝试了以下方法:

import numpy as np
y_1, z_1, x_1 = np.loadtxt('./data_set_1.txt').T    
y_2, z_2, x_2 = np.loadtxt('./data_set_2.txt').T

threshold = 0.000005
for i in z_1:
 for j in z_2:
   if abs(i - j) < threshold:
   print "i = ", ('%.13f' % i)
   print "j = ", ('%.13f' % j)

结果如下:

i =  -941.4594925722633
j =  -941.4594947788443
i =  -941.4456535625201
j =  -941.4456565008313
i =  -941.4291125503427
j =  -941.4291149979141
i =  -941.4326065311985
j =  -941.4326072530644
i =  -941.4098552554067
j =  -941.4098593315858
i =  -941.4138389914422
j =  -941.4138343941854
i =  -941.3961673813864
j =  -941.3961719676133
i =  -941.3984112845883
j =  -941.3984098947884
i =  -941.3838698217477
j =  -941.3838733787329
i =  -941.4001013025463
j =  -941.4001055479807

可以检查这是否有效,因为i = -941.4594925722633位于./data_set_1.datz_1列,而j = -941.4594947788443位于./data_set_2.dat。你知道吗

现在,每个打印的i结果都包含x_1y_1

类似地,这些j结果中的每一个都包含x_2y_2

我无法提取x_1y_1x_2y_2


Tags: 数据inhttpstxtcomfordatathreshold
2条回答

下面是一个可行方法的概要。你知道吗

z的值按递增顺序对每个数据集排序:即z_1z_2。然后为每个数据集设置一个索引。扫描它们,当该数据集中的项太低而无法与另一个数据集中指向的项进行比较时,前进一个索引。当比较的项目足够接近时,对这对项目进行操作。当两个索引都到达其数据集的末尾时,就完成了。这类似于mergesort的实现方式。不同大小的数据集不会影响算法。你知道吗

这个算法看起来并不特别像python,它没有使用numpy的优点,但是它的优点是它可以工作。第二阶段具有时间复杂性O(n),因此速度很快。排序阶段具有时间复杂性O(n log(n)),因此它是缓慢的部分。你知道吗


关于您添加的代码尝试:ij对于值z_1z_2来说是糟糕的变量名。如果ndx1ndx2是两个数据集的索引,相等的“阈值”是threshold,则可以使用以下方法测试近似相等:

if abs(z_1[ndx1] - z_2[ndx2]) < threshold:
   do_whatever

threshold的值类似于1e-5。你知道吗

但这里的代码与您想要的更为密切相关。这假设数据集已经设置好并按它们的z值排序。你知道吗

threshold = 1e-5

length1, length2 = len(z_1), len(z_2)
if length1 == 0 or length2 == 0:
    return
ndx1 = ndx2 = 0
z1, z2 = z_1[0], z_2[0]

while True:
    if z1 + threshold <= z2:  # z_1 too low
        ndx1 += 1
        if ndx1 == length1:
            return
        z1 = z_1[ndx1]
    elif z2 + threshold <= z1:  # z_2 too low
        ndx2 += 1
        if ndx2 == length2:
            return
        z2 = z_2[ndx2]
    else:  # z_1 and z_2 almost equal
        do_whatever
        # adjust ndx1, ndx2

这只是一副骷髅。最后如何调整ndx1ndx2,取决于是否允许z_1的一个值几乎大于z_2的值或相反。你知道吗

以下是仅使用numpy的粗略开始:

idx = abs(z1 - z2[:, None]) < threshold
idx1 = idx.any(0)
idx2 = idx.any(1)

idx1idx2可以用来获取相关的行,例如y1[idx1]y2[idx2]

代码的工作原理是对z1z2中的所有元素进行两两比较,然后找到其中一个比较小于阈值的任何元素。
对于一个大数据集,Rory的答案会更快,并且占用更少的内存,因为它只在需要的地方计算比较。对于较小的数据集(如给定的数据集),消除循环的加速应该是相当大的。你知道吗

相关问题 更多 >