Pythonic根据值将列表的部分分组为多个列表的方法

Pythonic根据值将列表的部分分组为多个列表的方法,python,list,for-loop,list-comprehension,Python,List,For Loop,List Comprehension,下面是我绘制的图,其中y轴v是列表中包含的值。如您所见,列表值在高值段和低值段之间交替,因此列表如下所示: li = [0.5,0.49,0.5,..,0.5,0.001,0.001,...,0.001,0.49,0.5,...,0.5,] 我的目标是分别取六段高值和六段低值,然后计算每段的平均值。为了做到这一点,我试图将上面的列表分开,并将每个段放入自己的列表中,并将每个列表放入各自的高值/低值列表中。大致如下: high_segments = [[high_values1],[high_v

下面是我绘制的图,其中y轴v是列表中包含的值。如您所见,列表值在高值段和低值段之间交替,因此列表如下所示:

li = [0.5,0.49,0.5,..,0.5,0.001,0.001,...,0.001,0.49,0.5,...,0.5,]
我的目标是分别取六段高值和六段低值,然后计算每段的平均值。为了做到这一点,我试图将上面的列表分开,并将每个段放入自己的列表中,并将每个列表放入各自的高值/低值列表中。大致如下:

high_segments = [[high_values1],[high_values2],[high_values3]]
low_segments  = [[low_values1],[low_values2],[low_values3]]
我一直试图构建一个for循环来实现这一点,但一直在努力解决如何处理低值组和高值组之间的变化。如有任何建议,我们将不胜感激


我假设您的输入数组li是连续的6个高值和6个低值,导致该数组有36个元素。首先,numpy.reformate函数创建一个连续的6元素子数组。然后,我们可以通过切片选择图中的奇数子数组高值和偶数子数组低值。通过第二个轴堆叠两个阵列将形成所需的形状。block_reduce函数将为每个块计算

import numpy as np
# conda install -c anaconda scikit-image
from skimage.measure import block_reduce

if __name__ == '__main__':
    li = np.arange(0, 36)
    li = li.reshape(-1, 6)
    high_values = li[::2]
    low_values = li[1::2]
    combined = np.stack((high_values, low_values), axis=1)
    segment_average = block_reduce(combined, block_size=(1,2,6), func=np.mean, cval=np.mean(combined)).flatten()
    print(f"[main] input:\n{li}")
    print(f"[main] high_values:\n{high_values}")
    print(f"[main] low_values:\n{low_values}")
    print(f"[main] combined:\n{combined}")
    print(f"[main] segment average: {segment_average}")
结果:

[main] input:
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]
 [24 25 26 27 28 29]
 [30 31 32 33 34 35]]
[main] high_values:
[[ 0  1  2  3  4  5]
 [12 13 14 15 16 17]
 [24 25 26 27 28 29]]
[main] low_values:
[[ 6  7  8  9 10 11]
 [18 19 20 21 22 23]
 [30 31 32 33 34 35]]
[main] combined:
[[[ 0  1  2  3  4  5]
  [ 6  7  8  9 10 11]]

 [[12 13 14 15 16 17]
  [18 19 20 21 22 23]]

 [[24 25 26 27 28 29]
  [30 31 32 33 34 35]]]
[main] segment average: [ 5.5 17.5 29.5]
使用numpy并按平均值拆分

import numpy as np

li = np.array([
    0.5, 0.49, 0.5,
    0.001, 0.001, 0.001,
    0.49, 0.5, 0.5,
    0, 0.002, 0.01,
])

# Split into high/low groups using the mean:
is_high = li >= li.mean()
is_low = li < li.mean()

# Determine the groups:
diff = np.insert(np.diff(is_high), 0, False).astype(np.int)  # array([0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0])
groups = diff.cumsum()  # array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3])

high_segments = np.array([li[groups==kk] for kk in np.unique(groups[is_high])])
low_segments = np.array([li[groups==kk] for kk in np.unique(groups[is_low])])

high_segments_mean = high_segments.mean(axis=1)
low_segments_mean = low_segments.mean(axis=1)

如果我的问题不完全清楚,我道歉。不幸的是,高连续数和低连续数的数量并不一致。每个段中的值的数量各不相同,因此可能是20高、23低、24高、21低,依此类推。这看起来很完美!非常感谢。你能解释一下从第二行到最后两行的代码在做什么吗。我不太熟悉这些numpy属性的用法。例如,insert和diff函数在这里做什么?is_high是真值和假值的数组。使用np.diff可以找到从高到低的转换位置,反之亦然。np.diff计算数组中每个值与其前面的值之间的差值。取这个差意味着数组中的值减少了一个,因此需要使用np.insert在索引0处插入一个额外的假值。然后,diff数组的累积和将为您提供组。