如何计算列表中值块的大小?
Posted
技术标签:
【中文标题】如何计算列表中值块的大小?【英文标题】: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]
如何计算此列表中1
和0
值块的大小?
结果列表将如下所示:
list_2 = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 1, 1]
【问题讨论】:
请考虑提供有关问题所在的更多详细信息。 根据文字要求,结果应为[1, 2, 3, 4, 1, 1]
。
【参考方案1】:
尝试使用cumsum
和diff
然后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】:这是一种使用shift
和cumsum
的方法
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]
【讨论】:
以上是关于如何计算列表中值块的大小?的主要内容,如果未能解决你的问题,请参考以下文章
计算下列数字两个图像块的二维DFT和二维DCT,并用Matlab编程验证计算结果
计算下列数字两个图像块的二维DFT和二维DCT,并用Matlab编程验证计算结果