【问题标题】:Sorting pairs in a list of varying dimension在不同维度的列表中对对进行排序
【发布时间】:2018-10-04 02:16:20
【问题描述】:

我有一个列表,其中包含不同大小的元素(有些甚至是空的):

a1 = [array([[83, 84]]), array([[21, 24], [32, 53],[54, 56]]), array([[21,24],[32, 37],[45, 46]]), [], []]

在这个列表中,值要么成对出现(在数组中),要么只是空的。我要做的就是根据它们的差异按降序对所有对进行排序,并将它们的位置/索引保留在原始列表中(即a1)。例如,我想要的输出是:

a1_sorted = [[32,53],[32,37],[21,24],[21,24],[54,56],[45,46],[83,84],[],[]] a1_index = [[1,1],[2,1],[1,0],[2,0],[1,2],[2,2],[0,0],[3,0],[4,0]]

由于空元素没有二维位置,下面仅指示元素的第一个索引也是一个合适的替代方案:

a1_index = [1,2,1,2,1,2,0,3,4]

简单地遍历列表条目是我最初的方法,但处理空元素和不同的维度大小减慢了这项工作。关于最佳解决方案的任何想法?

【问题讨论】:

  • 到目前为止,您是否为此编写过任何代码,或者您目前正在探索不同的解决方案?
  • a1的内容是numpy数组吗?
  • @zenwraight 我正在探索不同的解决方案。
  • @c2huc2hu 值对在 numpy 数组中,而空条目只是空列表。

标签: python arrays list sorting


【解决方案1】:

您可以使用enumerate 为列表和子列表生成索引,然后使用列表推导生成配对及其索引作为元组,以便一起排序以进行输出,并根据需要解压缩为两个不同的变量:

a1_sorted, a1_index = zip(*sorted(((t, [i, j])
                      for i, l in enumerate(a1) for j, t in enumerate(list(l) or [[]])),
                      key=lambda t: -abs(t[0][1] - t[0][0]) if len(t[0]) else 0))

a1_sorted 会变成:

[[32, 53], [32, 37], [21, 24], [21, 24], [54, 56], [83, 84], [45, 46], [], []]

a1_index 会变成:

[[1, 1], [2, 1], [1, 0], [2, 0], [1, 2], [0, 0], [2, 2], [3, 0], [4, 0]]

【讨论】:

  • 也许我有一个错误,但是在使用代码时(两种方法)我收到以下错误消息:File "<ipython-input-25-8e118b59b888>", line 2, in <genexpr> for i, l in enumerate(a1) for j, t in enumerate(l or [[]])), ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 是否与您在上面使用的a1 完全相同代码,你能重述它吗?
  • @Mathews24 我明白了。实际上,我在测试中没有使用 numpy 数组,因此在您的情况下,您必须将t[0] 替换为t[0].any() 作为第一种方法,将t 替换为t.any() 作为第二种方法,作为错误消息建议。
  • 仅对t[0] 进行尝试时,错误仍然存​​在。当我将t 转换为t.any() 时,我收到的错误是:File "<ipython-input-34-79d20e32a96d>", line 2 for i, l in enumerate(a1) for j, t.any() in enumerate(l or [[]])))) SyntaxError: can't assign to function call。也许我误解了您的建议;你能用特定的修改来更新你的答案吗?
  • @Mathews24 我明白了。我自己测试后更新了我的答案。但是,我认为第二种方法不适用于 numpy 数组,因此我将其删除。让我知道它是否适合您。
【解决方案2】:

你可以试试这个代码。但是,无法获取空列表

import numpy as np
import pandas as pd

# the data
a1 =  [np.array([[83, 84]]), np.array([[21, 24], [32, 53],[54, 56]]), 
       np.array([[21,24],[32, 37],[45, 46]]), np.array([]), 
       np.array([])]

# create a data frame to store data in
df = pd.DataFrame(columns=['pair', 'index', 'difference']) 

for j, item in enumerate(a1): 
    a = item.ravel() # convert 2d array to 1d array
    for i in range(len(a)//2):
        difference = a[i*2+1] - a[i*2]
        pair = [a[i*2], a[i*2+1]]
        index = [j, np.where(np.all(item==pair,axis=1))[0]]

        df.loc[len(df)] = [pair, index, difference]

df.sort_values(by='difference', ascending=False, inplace=True) # sort based on diff

print(df)

       pair     index difference
2  [32, 53]  [1, [1]]         21
5  [32, 37]  [2, [1]]          5
1  [21, 24]  [1, [0]]          3
4  [21, 24]  [2, [0]]          3
3  [54, 56]  [1, [2]]          2
0  [83, 84]  [0, [0]]          1
6  [45, 46]  [2, [2]]          1

a1_sorted =  df['pair'].tolist()
print(a1_sorted)

[[32, 53], [32, 37], [21, 24], [21, 24], [54, 56], [83, 84], [45, 46]]

【讨论】:

    猜你喜欢
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2022-11-13
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多