【问题标题】:How to sort two-dimensional array in python如何在python中对二维数组进行排序
【发布时间】:2014-09-23 10:09:27
【问题描述】:
Tool = [[0 for x in xrange(3)] for y in xrange(len(xTool)-1)]
for l in xrange((len(xTool) - 1)):
  Tool[l][0] = yTool[l]; Tool[l][1] = xTool[l]; Tool[l][2] = zTool[l]  

我从点坐标开始,它们在 3 个列表(xTool、yTool、zTool)中,分别代表我所有点的 x、y 和 z 坐标。

这里的目的是创建一个包含 3 列和多行(超过 10,000 行)的矩阵,其中每行代表点的 3 个坐标。我要做的下一步是像这样的向量转换:(这并不重要,只有当你真的想了解我在做什么时

rTool = numpy.zeros_like(Tool)   
for rt in xrange((len(xTool) - 1)):
  rTool[rt][0] = (Tool[rt][0] * cos(angle)) - (Tool[rt][1] * sin(angle))
  rTool[rt][1] = (Tool[rt][0] * sin(angle)) + (Tool[rt][1] * cos(angle))
  rTool[rt][2] = Tool[rt][2]

最后,我要做的是针对我的第二列 ([1]) 订购我的 rTool。例如,我打印了 5 个 rTool 条目。通过根据第二列对它们进行排序,最后一行应该是第一行。我真的很难做到这一点,我怀疑这是因为我有元组而不是真正的 3 列数学矩阵。

[[ -584.89837646 -3648.6472168    402.177948  ]
 [ -542.8659668  -3663.34545898   405.76959229]
 [ -500.831604   -3678.04785156   409.32122803]
 [ -458.79336548 -3692.75854492   412.7930603 ]
 [ -416.74984741 -3637.48022461   416.15090942]]

不要犹豫,要求澄清,我希望你能帮助我!谢谢。

【问题讨论】:

  • 5 年前提出的类似问题stackoverflow.com/questions/613183/…
  • 您可能希望使用元组作为坐标,因此您将拥有一个三元组列表[(x, y, z,)(x, y, z)]。元组是不可变的,但速度更快。

标签: python arrays sorting numpy tuples


【解决方案1】:

首先,学习 numpy。用普通的python做这种事情违背了pythonic的一切。

一旦你这样做了:

sorted_rtool = rTool[np.argsort(rTool[:,1])]

推动 numpy home 的重要性:

rTool = np.dot(Tool, R)

不仅干净得多,而且速度也快了几个数量级。

【讨论】:

  • 为什么它会与pythonic的一切相悖?
  • 'Everything' 是一个大词,但它在所有可以想象的方面都完全是错误的工作工具。在 python 中重新发明诸如矩阵乘法之类的东西对于初学者来说是重新发明轮子的糟糕案例。此外,它掩盖了代码的意图,更容易出错,而且性能肯定会受到数量级的影响。
  • 我会说这通常是正确的,但我真的不喜欢 numpy 重用 np.dot() 进行矩阵乘法、求和积以及点积的方式。我会争辩说这是不合情理的,因为它掩盖了实际发生的事情。如果你要说“使用 numpy,因为你可以让它更 Pythonic 而不是重新发明轮子”,那么你应该推荐使用 matrix 类,然后你只需要做 M * N 来实现你想要的.我认为这比np.dot(M,N) 更像pythonic
  • 如果 Eelco 有勇气推荐使用 matrix 类,我希望他已经准备好迎接投票风暴...... ;-) 说真的,numpy 的 matrix 类是疼痛,最好避免。等一年左右,用 numpy 1.10 和 Python 3.5 你可以做M @ N,见PEP 465。
  • 好吧,我认为我一直是对提议的 @ 运算符最直言不讳的批评者,我觉得它只比使用矩阵类好一个档次,所以你也不会看到我推荐 ;)。就个人而言,我将 einsum 用于几乎所有线性产品,因为我不喜欢跟踪关于哪些轴去哪里的约定。显式优于隐式。点如何掩盖实际发生的事情?虽然它没有使坐标轴显式化,但它比乘法运算符要显式得多,乘法运算符在应用于数组时可能意味着十几种不同的东西。
【解决方案2】:

你可以使用'sort'或'sorted'的'key'参数,见https://wiki.python.org/moin/HowTo/Sorting#Key_Functions

在你的情况下:

rTool.sort(key=lambda x: x[1])

或

rToolSorted = sorted(rTool, key=lambda x: x[1])

【讨论】:

    【解决方案3】:

    您正在寻找list.sort() 的key 关键字(或内置sorted())查看Key Functions 部分here。

    人们通常只使用 lambda 函数作为排序键,因为它很简洁,而且您通常不会多次使用排序函数。它只是一个函数,它返回一个对象key,列表的每个元素都在该对象上进行排序。

    所以你可以这样做:

    def keyFunc(element):
      return element[1]
    
    rTool.sort(key=keyFunc)
    

    或:

    rTool.sort(key=lambda x: x[1])
    

    在这两种情况下,您都可以改用rTool = sorted(rTool, key=...),区别在于list.sort() 进行就地排序,如果您不需要原始数组,效率会更高。

    key 函数可以是你想要的任何东西,只要它返回可以排序的其他东西,所以如果你的点是具有x, y, z 属性的对象,那么你可以使用rTool.sort(key x: x.y)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-30
      • 2013-09-13
      • 1970-01-01
      • 2013-08-17
      • 2021-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多