【问题标题】:How to structure multiple python arrays for sorting如何构造多个python数组进行排序
【发布时间】:2017-02-22 00:01:39
【问题描述】:

我正在执行的傅立叶分析输出 5 个数据字段,我将每个数据字段收集到 1-d numpy 数组中:频率 bin #、幅度、波长、归一化幅度、%power。

如何最好地构建数据以便我可以按幅度降序排序?

当只使用一个数据字段进行测试时,我可以使用如下的字典:

fourier_tuples = zip(range(len(fourier)), fourier)
fourier_map = dict(fourier_tuples)
import operator
fourier_sorted = sorted(fourier_map.items(), key=operator.itemgetter(1))
fourier_sorted = np.argsort(-fourier)[:3]

我的意图是将其他数组添加到第 1 行,但这不起作用,因为 dicts 只接受 2 个术语。 (这就是为什么this post 没有解决我的问题。)

退一步说,这是一种合理的方法,还是有更好的方法来组合和排序单独的数组?最终,我想从前 3 个频率和相关的其他数据中获取数据值,并将它们写入输出数据文件。

这是我的数据的 sn-p:

fourier = np.array([1.77635684e-14, 4.49872050e+01, 1.05094837e+01, 8.24322470e+00, 2.36715913e+01])
freqs = np.array([0.        ,  0.00246951,  0.00493902,  0.00740854,  0.00987805])
wavelengths = np.array([inf, 404.93827165, 202.46913583, 134.97942388, 101.23456791])
amps = np.array([4.33257766e-16, 1.09724890e+00, 2.56328871e-01, 2.01054261e-01, 5.77355886e-01])
powers% = np.array([4.8508237956526163e-32, 0.31112370227749603, 0.016979224022185751, 0.010445983875848858, 0.086141014686372669])

最后 4 个数组是 'fourier' 对应的其他字段。 (实际数组长度为 42,但为简单起见减少到 5。)

【问题讨论】:

  • 你能添加一些数据吗?!
  • 数组?你的意思是列表吗?为什么你使用dict,然后只是调用items?这没有任何意义......
  • zip(range(len(fourier)), fourier) 的缩写enumerate(fourier)?
  • @juanpa.arrivillaga,我没有提到我在 numpy 工作;是的,这些是数组,而不是列表。我正在尝试修改我在其他地方看到的方法以满足我的需要。它似乎按预期工作,直到我开始使用多个数组。我正在调用项目,因为我的可迭代 b/c 排序不适用于字典。我是新手,我确定有更好的方法。我全神贯注。
  • @PaulPanzer:是的,它们似乎包含相同的信息。我没有使用 enumerate(),但似乎无法将结果打印到控制台,因为我可以创建我创建的 'fourier_tuples' 数组。

标签: arrays sorting numpy


【解决方案1】:

您似乎正在使用 numpy,所以这里是 numpy 执行此操作的方法。您的帖子中有正确的函数np.argsort,但您似乎没有正确使用它:

order = np.argsort(amplitudes)

这类似于您的字典技巧,只是它计算与您的过程相比的反向洗牌。顺便提一句。为什么要通过字典而不是简单的元组列表?

order 的内容现在是amplitudes 的索引order 的第一个单元格包含amplitudes 的最小元素的位置,第二个单元格包含下一个元素的位置等等。因此

top5 = order[:-6:-1]

如果您的数据是 1d numpy arrays,您可以使用 top5 通过使用高级索引

提取对应于前 5 个幅度的元素
freq_bin[top5]
amplitudes[top5]
wavelength[top5]

如果您愿意,您可以将它们按列分组,并将top5 应用于生成的 n×5 数组:

np.c_[freq_bin, amplitudes, wavelength, ...][top5, :]

【讨论】:

  • 我是 numpy 的新手,只是在模仿我在其他地方看到的方法。我并不惊讶这不是最好的方法。如果元组更合理,那就更好了。我创建了这样的元组:fourier_tuples = zip(range(len(fourier)), freqs, wavelengths, fourier, amps, powers)。然后如上所述创建“top5”并运行fourier_tuples[top5]。结果:“TypeError:只有一个元素的整数数组可以转换为索引”
  • @joechoj 如果您想按照最初尝试的方式工作,我的意思是元组。当您调用.items() 时,您的字典的键值对将转换为元组,但这样您只能对 2 个进行分组,使用元组列表可以对所有组进行分组。 - 正如我在回答中所说,如果你想使用我的方法,你必须使用 numpy 数组,因为它们了解高级索引,而元组则不。 numpy 术语中 zip 的等价物是最后一行中的 np.c_[...]
【解决方案2】:

如果我理解正确,您有 5 个长度相同的单独列表,并且您正尝试根据其中之一对所有列表进行排序。为此,您可以使用 numpy 或使用 vanilla python。这是我脑海中的两个例子(排序基于第二个列表)。

a = [11,13,10,14,15]
b = [2,4,1,0,3]
c = [22,20,23,25,24]

#numpy solution
import numpy as np

my_array = np.array([a,b,c])
my_sorted_array = my_array[:,my_array[1,:].argsort()]

#vanilla python solution
from operator import itemgetter

my_list = zip(a,b,c)
my_sorted_list = sorted(my_list,key=itemgetter(1))

如果您愿意,可以使用 my_sorted_array = np.fliplr(my_sorted_array) 翻转数组,或者如果您正在使用列表,您可以使用 my_sorted_list.reverse() 将其反转

编辑:

要仅获取前 n 个值,您必须简单地 slice 数组,类似于 @Paul 的建议。通过指定start:stop:step(您可以省略该步骤)参数,切片以与经典列表切片类似的方式完成。在您的 5 个顶部列的情况下,它将是 [:,-5:]。因此,在上面的示例中,您可以像这样从每一行中取出前 2 列:

my_sliced_sorted_array = my_sorted_array[:,-2:]

结果将是:

array([[15, 13],
       [ 3,  4],
       [24, 20]])

希望对你有帮助。

【讨论】:

  • 我喜欢 numpy 解决方案,但不能让它发挥作用。我按照您的建议创建了一个“my_flipped_array”。可以截断数组以仅包含前 x 值吗?虽然也许我不需要这样做,因为结果都可以通过索引访问......
  • 啊,谢谢。我一直在尝试“my_flipped_array[:][:3]”,它最终以某种方式返回了整个数据集。知道为什么这不起作用吗?相比之下,'my_flipped_array[0][:3]' 确实从第一个数组返回前 3 个值。
  • 谁否决了这个答案,你能解释一下吗?这对我来说似乎是一个很好的方法......有什么原因我会遇到问题吗? @Paul Panzer 的答案是否更可取?
猜你喜欢
  • 2015-01-18
  • 2016-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
相关资源
最近更新 更多