Python:根据升序x数组对y值数组进行排序

时间:2015-08-14 22:16:36

标签: python arrays sorting

如果我有两个表格阵列:

x = [0, 7, 2, 4, 6, 9, 5]

y = [1, 2, 3, 4, 5, 6, 7]

即,我的数据点位于[0,1][3,2][x_n,y_n]等。我如何组织y以获得相应的升序x值?换句话说,我最终得到的值为x

x = [0, 2, 4, 5, 6, 7, 9]

与相应的y值匹配:

y = [1, 3, 4, 7, 5, 2, 6]

我猜我需要将两个数组拼接在一起,然后根据x排序,但我不太确定这个的确切语法。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:6)

我会将ziplambda

一起使用
In [55]: x = [0, 7, 2, 4, 6, 9, 5]

In [56]: y = [1, 2, 3, 4, 5, 6, 7]

In [57]: L = sorted(zip(x,y), key=operator.itemgetter(0))

In [58]: new_x, new_y = zip(*L)

In [59]: new_x
Out[59]: (0, 2, 4, 5, 6, 7, 9)

In [60]: new_y
Out[60]: (1, 3, 4, 7, 5, 2, 6)

不要忘记导入operator

答案 1 :(得分:3)

sorted之后,您可以zip将它们作为元组

>>> sorted((i,j) for i,j in zip(x,y))
[(0, 1), (2, 3), (4, 4), (5, 7), (6, 5), (7, 2), (9, 6)]

要迭代这些对,你可以做类似

的事情
sorted_pairs = sorted((i,j) for i,j in zip(x,y))
for i,j in sorted_pairs:
    # do something with each i and j value, which are x and y respectively

或者您可以直接索引

sorted_pairs[0][0]  # x of the first tuple
sorted_pairs[0][1]  # y of the first tuple
sorted_pairs[3][0]  # x of the fourth tuple... etc

答案 2 :(得分:0)

我喜欢其他例子(从他们那里学到的东西)。我的回答方向有点不同:首先将x项转换为(index,x [index])元组,根据元组中的第2项对这样的列表进行排序,将索引作为列表输出并使用从y列表中选择值的索引列表。

这种方法可能会有效,如果有更多的列表,如y,则应根据列表x中的项目顺序进行排序。

简明版

>>> x = [0, 7, 2, 4, 6, 9, 5]
>>> y = [1, 2, 3, 4, 5, 6, 7]
>>> from operator import itemgetter
>>> pick_0 = itemgetter(0)
>>> pick_1 = itemgetter(1)
>>> x_decor = sorted(enumerate(x), key=pick_1)
>>> x_idxs = map(pick_0, x_decor)
>>> multi_picker = itemgetter(*x_idxs)
>>> multi_picker(y)
(1, 3, 4, 7, 5, 2, 6)

让我解释一下它是如何工作的以及为什么它在某些情况下可能是相关的。

装饰,排序,获取索引,使用它们来选择结果项

首先,获取要使用的值:

>>> x = [0, 7, 2, 4, 6, 9, 5]
>>> y = [1, 2, 3, 4, 5, 6, 7]

然后使用enumerate使用列表x中项目的索引来装饰值:

>>> x_decor = [(idx, val) for idx, val in enumerate(x)]
>>> x_decor
[(0, 0), (1, 7), (2, 2), (3, 4), (4, 6), (5, 9), (6, 5)]

根据值排序装饰列表(现为itm[1],因为itm[0]是原始位置索引):

>>> x_decor.sort(key=lambda itm: itm[1])
>>> x_decor
[(0, 0), (2, 2), (3, 4), (6, 5), (4, 6), (1, 7), (5, 9)]

最后得出与排序x相关的位置索引列表:

>>> x_idxs = [idx for idx, val in x_decor]
>>> x_idxs
[0, 2, 3, 6, 4, 1, 5]

现在我们使用x_idxsy列表中选择相关项:

>>> y_vals = [y[idx] for idx in x_idxs]
>>> y_vals
[1, 3, 4, 7, 5, 2, 6]

对于其他列表(如果有的话),可以重复这最后一步。

使用itemgetter

的优化版本

可以使用itemgetter优化(速度)以前的代码。

itemgetter可以创建一个功能,允许从特定位置选择值。 itemgetter也可以创建函数,允许一次从预定义的位置选择多个值。

>>> from operator import itemgetter
>>> itemgetter(0)
<operator.itemgetter at 0x7f8e300afd90>
>>> pick_0 = itemgetter(0)
>>> pick_1 = itemgetter(1)
>>> pick_0_2 = itemgetter(0, 2)

让我们看看,这些功能可以为我们做些什么:

>>> pick_0(["a", "b", "c"])
'a'
>>> pick_1(["a", "b", "c"])
'b'
>>> pick_0_2(["a", "b", "c"])
('a', 'c')

让我们像以前一样创建装饰x,这次使用更短的语法:

>>> x_decor = sorted(enumerate(x), key=pick_1)
>>> x_decor
[(0, 0), (2, 2), (3, 4), (6, 5), (4, 6), (1, 7), (5, 9)]

enumerate(x)创建装饰列表,使用key=pick_1对其进行排序,以根据原始x列表中的值对其进行排序。

使用pick_0,我们可能只得到装饰列表中的索引列表:

>>> x_idxs = map(pick_0, x_decor)
>>> x_idxs
[0, 2, 3, 6, 4, 1, 5]

这些索引可用于创建multi_picker(与上面的pick_0_2类似):

>>> multi_picker = itemgetter(*x_idxs)
>>> multi_picker
<operator.itemgetter at 0x7f8e300afb10>

并使用multi_picker从列表y获取正确排序的元素:

>>> y_vals = multi_picker(y)
>>> y_vals
(1, 3, 4, 7, 5, 2, 6)

如果我们要根据排序的x元素排序更多列表,multi_picker将是现在唯一要调用它们的函数。

答案 3 :(得分:0)

嘿,我已经写了这个函数:

def sort_bar(bar_list):
    sorted_x = []
    sorted_x.extend(bar_list['x'])
    sorted_x.sort()
    sorted_y = []
    for x in sorted_x:
        sorted_y.append(bar_list['y'][bar_list['x'].index(x)])
    return {"x": sorted_x, "y": sorted_y}

示例:

unsorted = {
    "x": [5, 9, 2, 3],
    "y": [8, 6, 3, 4]
}
sorted = sort_bar(unsorted)