合并排序二维数组

时间:2018-11-16 22:19:57

标签: python multidimensional-array mergesort

我再次尝试使这种合并排序工作。 目前,我有一个带有Unix时间码的2d数组(图1),并使用(图2)合并排序。我试图检查每个数组中的第一个值,即array [x] [0],然后根据array [x] [0]值,但是,合并排序会创建重复数据并删除其他数据(图3)。我的问题是我在做什么错?我知道这是合并排序,但看不到解决方法。

图1

[[1422403200        100]
 [1462834800        150]
 [1458000000         25]
 [1540681200        150]
 [1498863600        300]
 [1540771200        100]
 [1540771200        100]
 [1540771200        100]
 [1540771200        100]
 [1540771200        100]]

图2

import numpy as np


def sort(data):
    if len(data) > 1:
        Mid = len(data) // 2
        l = data[:Mid]
        r = data[Mid:]
        sort(l)
        sort(r)

        z = 0
        x = 0
        c = 0

        while z < len(l) and x < len(r):
            if l[z][0] < r[x][0]:
                data[c] = l[z]
                z += 1
            else:
                data[c] = r[x]
                x += 1
            c += 1

        while z < len(l):
            data[c] = l[z]
            z += 1
            c += 1

        while x < len(r):
            data[c] = r[x]
            x += 1
            c += 1
        print(data, 'done')
unixdate = [1422403200, 1462834800, 1458000000, 1540681200, 1498863600, 1540771200, 1540771200,1540771200, 1540771200, 1540771200]
price=[100, 150, 25, 150, 300, 100, 100, 100, 100, 100]
array = np.column_stack((unixdate, price))
sort(array)
print(array, 'sorted')

图3

[[1422403200        100]
 [1458000000         25]
 [1458000000         25]
 [1498863600        300]
 [1498863600        300]
 [1540771200        100]
 [1540771200        100]
 [1540771200        100]
 [1540771200        100]
 [1540771200        100]] 

1 个答案:

答案 0 :(得分:-1)

我在您的代码中找不到任何错误。

我已经尝试过您的代码,并且可以说至少在常规的Python列表中不会发生此问题:该函数不会更改列表中任何元素的出现次数。

data = [
 [1422403200, 100],
 [1462834800, 150],
 [1458000000,  25],
 [1540681200, 150],
 [1498863600, 300],
 [1540771200, 100],
 [1540771200, 100],
 [1540771200, 100],
 [1540771200, 100],
 [1540771200, 100],
]

sort(data)

from pprint import pprint
pprint(data)

输出:

[[1422403200, 100],
 [1458000000, 25],
 [1462834800, 150],
 [1498863600, 300],
 [1540681200, 150],
 [1540771200, 100],
 [1540771200, 100],
 [1540771200, 100],
 [1540771200, 100],
 [1540771200, 100]]

编辑,要考虑到numpy上下文和np.column_stack的使用。

-我希望发生的情况是np.column_stack实际上在两个数组上创建了一个 view 映射。要获得真实的数组而不是指向现有数组的链接,应copy该数组:-

array = np.column_stack((unixdate, price)).copy()


编辑2 ,并考虑到numpy上下文

此行为实际上与np.column_stack没有关系; np.column_stack已执行复制。

您的代码不起作用的原因是因为numpy的切片行为与python不同。切片会创建映射索引的数组的视图

错误的行是:

l = data[:Mid]
r = data[Mid:]

由于lr仅映射到data所保存的两个内存,因此在data被修改时会对其进行修改。这就是data[c] = l[z]data[c] = r[x]行覆盖值并在移动值时创建副本的原因。

如果data是一个numpy数组,我们希望lr是数据的副本,而不仅仅是视图。这可以使用copy方法来实现。

l = data[:Mid]
r = data[Mid:]
if isinstance(data, np.ndarray):
    l = l.copy()
    r = r.copy()

通过这种方式,我测试了复制的效果。


注意

如果您要使用python列表而不是numpy数组对数据进行排序,那么在香草python中,np.column_stack的等效项是zip

z = zip([10, 20, 30, 40], [100, 200, 300, 400], [1000, 2000, 3000, 4000])
z
# <zip at 0x7f6ef80ce8c8>
# `zip` creates an iterator, which is ready to give us our entries.
# Iterators can only be walked once, which is not the case of lists.

list(z)
# [(10, 100, 1000), (20, 200, 2000), (30, 300, 3000), (40, 400, 4000)]

条目是(非可变的)元组。如果您需要条目可编辑,请在其上列出地图:

z = zip([10, 20, 30, 40], [100, 200, 300, 400], [1000, 2000, 3000, 4000])
li = list(map(list, z))
# [[10, 100, 1000], [20, 200, 2000], [30, 300, 3000], [40, 400, 4000]]

要转置矩阵,请使用zip(*matrix)

def transpose(matrix):
    return list(map(list, zip(*matrix)))

transpose(l)
# [[10, 20, 30, 40], [100, 200, 300, 400], [1000, 2000, 3000, 4000]]

您还可以使用li对python列表li.sort()进行排序,或使用sorted(li)对任何迭代器(列表为迭代器)进行排序。

在这里,我将使用(经过测试):

sorted(zip(unixdate, price))