【问题标题】:How to calculate the size of blocks of values in a list?如何计算列表中值块的大小?
【发布时间】:2021-02-08 00:11:57
【问题描述】:

我有一个这样的列表:

list_1 = [0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1]

如何计算此列表中10 值块的大小? 结果列表将如下所示:

list_2 = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 1, 1]

【问题讨论】:

  • 请考虑提供有关问题所在的更多详细信息。
  • 根据文字要求,结果应为[1, 2, 3, 4, 1, 1]

标签: python arrays pandas list numpy


【解决方案1】:

尝试使用cumsumdiff 然后transform count

s = pd.Series(list_1)
s.groupby(s.diff().ne(0).cumsum()).transform('count')
Out[91]: 
0     1
1     2
2     2
3     3
4     3
5     3
6     4
7     4
8     4
9     4
10    1
11    1
dtype: int64

【讨论】:

  • 你能解释一下吗?我想了解这些方法>?
  • @adirabargil 首先做 diff 和 eq 值返回不是 0 表示值改变然后我们做 cumsum 并创建子组键
【解决方案2】:

NumPy 方式 -

In [15]: a = np.array(list_1)

In [16]: c = np.diff(np.flatnonzero(np.r_[True,a[:-1] != a[1:],True]))

In [17]: np.repeat(c,c)
Out[17]: array([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 1, 1])

10,000x 给定示例的平铺版本的时间安排:

In [45]: list_1
Out[45]: [0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1]

In [46]: list_1 = np.tile(list_1,10000).tolist()

# Itertools groupby way :
In [47]: %%timeit
    ...: result = []
    ...: for k, v in groupby(list_1):
    ...:     length = len(list(v))
    ...:     result.extend([length] * length)
28.7 ms ± 435 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

# Pandas way :
In [48]: %%timeit
    ...: s = pd.Series(list_1)
    ...: s.groupby(s.diff().ne(0).cumsum()).transform('count')
28.3 ms ± 324 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

# NumPy way :
In [49]: %%timeit
    ...: a = np.array(list_1)
    ...: c = np.diff(np.flatnonzero(np.r_[True,a[:-1] != a[1:],True]))
    ...: np.repeat(c,c)
8.16 ms ± 76.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

【讨论】:

    【解决方案3】:

    您可以使用from itertools import groupby,因为groupby(list_1) 将产生以下结构

    >> [(k, list(v)) for k, v in groupby(list_1)]
    [(0, [0]), (1, [1, 1]), (0, [0, 0, 0]), (1, [1, 1, 1, 1]), (0, [0]), (1, [1])]
    

    然后只需迭代并添加与列表长度一样多的框

    result = []
    for k, v in groupby(list_1):
        length = len(list(v))
        result.extend([length] * length) # list of value 'length' of size 'length'
    
    print(result)  # [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 1, 1]
    

    【讨论】:

      【解决方案4】:

      这是一种使用shiftcumsum的方法

      s.groupby((s != s.shift()).cumsum()).transform('size')
      

      【讨论】:

        【解决方案5】:

        您可以只计算具有相同值的项目的出现次数

        def get_counts():
            counts = []
            previous = -1
            group_index = -1
            for x in list_1:
                if previous == x:
                    counts[group_index] += 1
                else:
                    group_index += 1
                    counts.append(1)
                previous = x 
            return counts
        

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

        然后

        list_2 = []
        for i in get_counts():
            list_2 += [i] * i 
        

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

        【讨论】:

          猜你喜欢
          • 2015-07-22
          • 1970-01-01
          • 2011-12-16
          • 2022-06-16
          • 2019-03-17
          • 2017-09-23
          • 2021-05-01
          • 2014-09-27
          相关资源
          最近更新 更多