如何根据数组的长度重新排列存储在列表中的 numpy 数组 [英] How to rearrange numpy arrays stored in a list based on the lengths of the arrays

查看:23
本文介绍了如何根据数组的长度重新排列存储在列表中的 numpy 数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 numpy 数组列表,想根据每个数组的长度重新排列它.这是我的清单:

I have a list of numpy arrays and want to rearrange it based on the length of each array. This is my list:

nums=[np.array([[2.], [3.]]), np.array([[8.], [7.], [1.]]),\
      np.array([[1.], [0.], [5.]]), np.array([[8.], [9.]]), np.array([[7.], [6.]])]

当数组的长度发生变化时,这一点很重要.长度列表是:

It is important when the length of arrays change. The list of lengthes is:

lns=[2, 3, 3, 2, 2]

基于lns,长度从第一个数组变为第二个数组.第一个数组较短,我想要它的所有行.我想要 2 (较短数组的长度)较长(第二个)行.在这种情况下,较短数组 (2.5) 的平均值小于较长数组 (5.3) 的平均值,因此我提取前 2 行较长的数组.我想要第二个和第三个数组,因为它们的长度是最大的.从第三到第四,长度发生变化.我再次想要所有较短的行和 2 (较短的长度,即第四行).但是,较短 (8.5) 的平均值高于较长 (2.).所以,我需要较长行的最后 2 行.最后,我想重新排列我的列表以获得以下列表:

Based on lns, length changes from first to second array. First array is shorter and I want all rows of it. I want 2 (length of shorter array) rows of longer (second) one. In this case the average of shorter array (2.5) is less than the average of longer (5.3), so I extarct the first 2 rows of the longer array. I want both second and third arrays because their lengths are maximum. From the third to the fourth the length changes. Again I want all rows of shorter and 2 (length of shorter, i.e. fourth). But, the average of shorter (8.5) is higher than longer (2.). So, I need the last 2 rows of the longer one. Finally, I want to rearrange my list to get the following one:

final=[np.array([[2.], [3.], [8.], [7.]]),\ # all rows of first and first 2 rows of second
       np.array([[8.], [7.], [1.], [1.], [0.], [5.]]),\
       np.array([[0.], [5.], [8.], [9.], [7.], [6.]])]# last 2 rows of third and all rows of next short arrays

我非常感谢在 python 中做我想做的任何帮助.

I do appreciate any help to do what I want in python.

推荐答案

1.首先,我使用 pairwise() itertools 的配方,一次获取两个连续的元素,而不是使用索引:

1. First, I'm using the pairwise() recipe from itertools to get two successive elements at a time, instead of using indexes:

import itertools

# https://docs.python.org/3/library/itertools.html#itertools-recipes
def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = itertools.tee(iterable)
    next(b, None)
    return zip(a, b)

2.我创建了一个辅助函数 first_or_last() 它返回一个 slice 对象 可以用于一个 numpy 数组,并应用于被比较的两个相邻数组中较大的3.根据您上面描述的逻辑,需要应用哪个切片取决于平均值/平均值.如果需要,您可以将其减少为两行功能,我使用较长的版本进行注释/解释.

2. I created a helper function first_or_last() which returns a slice object which can be used on a numpy array, and is applied to the larger of the two neighbouring arrays3 being compared. Which slice needs to be applied depends on the average/mean value, as per the logic you described above. You can reduce it to a two-line function if you want, I've used the longer version for comments/explanation.

def first_or_last(smaller, larger):
    """return a slice object for either the first-n items or
    the last-n items of the larger array
    """
    size = len(smaller)
    if np.mean(smaller) < np.mean(larger):
        # take first-`size` elements
        return slice(None, size)
    # take last-`size` elements
    return slice(-size, None)  # don't skip the extra None, needed for axes
    # or just
    # return slice(None, size) if np.mean(smaller) < np.mean(larger) else slice(-size, None)

3 .重新排列的代码:

3 . The code which does the re-arranging:

nums = [np.array([[2.], [3.]]), np.array([[8.], [7.], [1.]]),
        np.array([[1.], [0.], [5.]]), np.array([[8.], [9.]]),
        np.array([[7.], [6.]])]

final = []
for ar1, ar2 in pairwise(nums):
    l1, l2 = len(ar1), len(ar2)
    if l1 == l2:  # same length
        final.append(np.append(ar1, ar2, axis=0))
        continue
    # different lengths
    arrs = (ar1, ar2[first_or_last(ar1, ar2)]) if l1 < l2 else (ar1[first_or_last(ar2, ar1)], ar2)
    final.append(np.append(*arrs, axis=0))

final 的值:

[array([[2.], [3.], [8.], [7.]]),
 array([[8.], [7.], [1.], [1.], [0.], [5.]]),
 array([[0.], [5.], [8.], [9.]]),
 array([[8.], [9.], [7.], [6.]])]


注意事项:


Notes:

  1. 它的输出与 final 的输出不同.见 我的评论中的第 9 项,因为我没有看到使结果有 3 个而不是 4 个的规则/逻辑.

  1. The output of this differs from what you have as final. See item #9 in my comment, as I don't see the rule/logic that would make the result have 3 items and not 4.

9. 另一个逻辑上的不一致:对于数组 3(len 3)和数组 4(len 2),结果应该是 0 5 8 9 和结果中的最后一项应该是 8 9 7 6.为什么最后将它们合并为 0 5 8 9 7 6 ?他们应该是分开的.为第 3、第 4 和第 5 个数组合并它们而不是第 1、第 2 和第 5 个数组的逻辑是什么?第三个数组?

9. Another inconsistency in the logic: for array 3 (len 3) and array 4 (len 2), the result should be 0 5 8 9 and the last item in the result should be 8 9 7 6. Why are these merged into one as 0 5 8 9 7 6 at the end? They should be separate. What's the logic to merge them all for the 3rd, 4th and 5th arrays but not for the 1st, 2nd & 3rd arrays?

  • 此解决方案不会为您之前的/原始问题出错,但似乎也没有成为正确的输出 - 即使它确实遵循相同的规则.

  • This solution won't give errors for your previous/original question but it also doesn't seem to be the right output - even though it does follow the same rules.

    NumPy 数组切片返回原始数组的视图,而不是副本.

    NumPy array slicing returns a view on the orignal array, not a copy.

    这篇关于如何根据数组的长度重新排列存储在列表中的 numpy 数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆