如何在Python中统计相邻同值点并按计数分组标记
问题描述
现有以下Python测试脚本,生成随机0-1矩阵并以红/黄背景可视化:
import numpy as np import pandas as pd # Generating dummy data for testing ROWS=10 COLS=20 X = np.random.randint(2, size=(ROWS, COLS)) # Visualizing df = pd.DataFrame(data=X) bg='background-color: ' df.style.apply(lambda x: [bg+'red' if v>=1 else bg+'yellow' for v in x])
需求:对每行中无间隔的相邻同值元素进行分组,统计每组的元素数量,并为每个元素标记对应的组编号和计数,最终可视化区分不同组。
解决方案
可以通过逐行识别连续同值段生成分组标记,再结合样式可视化区分组。以下是两种实现方式:
方式1:纯Python循环实现(直观易懂)
import numpy as np import pandas as pd # 生成测试数据 ROWS = 10 COLS = 20 X = np.random.randint(2, size=(ROWS, COLS)) df = pd.DataFrame(data=X) # 为每行生成连续同值分组标记 def mark_consecutive_groups(row): marks = [] if len(row) == 0: return marks current_val = row.iloc[0] count = 1 group_num = 1 for val in row.iloc[1:]: if val == current_val: count += 1 else: marks.extend([f"组{group_num}({count})"] * count) current_val = val count = 1 group_num += 1 # 处理最后一组 marks.extend([f"组{group_num}({count})"] * count) return marks # 生成标记DataFrame mark_df = df.apply(mark_consecutive_groups, axis=1, result_type='expand') # 自定义样式:按组分配不同背景色 def style_groups(row): bg = 'background-color: ' # 定义组对应的背景色(可根据需要扩展) color_map = { "组1": "#ffcccc", "组2": "#ccffcc", "组3": "#ccccff", "组4": "#ffffcc", "组5": "#ffccff", "组6": "#ccffff" } styles = [] for mark in mark_df.loc[row.name]: group_prefix = mark.split('(')[0] # 若组编号超过预设,用白色兜底 color = color_map.get(group_prefix, "#ffffff") styles.append(f"{bg}{color}") return styles # 合并原始数据与标记,应用样式展示 combined_df = pd.concat([df, mark_df], axis=1, keys=['原始值', '分组标记']) combined_df.style.apply(style_groups, axis=1)
方式2:Numpy优化实现(效率更高)
利用np.diff快速定位值变化的位置,适合处理大规模数据:
def mark_consecutive_groups_np(row): row_np = row.to_numpy() # 找到值发生变化的索引位置 change_indices = np.where(np.diff(row_np) != 0)[0] + 1 # 将行分割为连续同值的段 segments = np.split(row_np, change_indices) # 生成标记 marks = [] for group_idx, seg in enumerate(segments, 1): marks.extend([f"组{group_idx}({len(seg)})"] * len(seg)) return marks # 生成标记DataFrame mark_df_np = df.apply(mark_consecutive_groups_np, axis=1, result_type='expand') # 样式应用与方式1一致,直接复用style_groups函数即可 combined_df_np = pd.concat([df, mark_df_np], axis=1, keys=['原始值', '分组标记']) combined_df_np.style.apply(style_groups, axis=1)
说明
- 两种方式都会为每个元素生成类似
组1(3)的标记,其中组1是组编号,3是该组的连续同值元素数量。 - 样式函数通过组编号分配不同背景色,直观区分不同的连续同值组。
- 若需要仅标记原始值的样式(不显示标记文本),可直接对原始DataFrame应用
style_groups逻辑,跳过合并标记的步骤。
内容的提问来源于stack exchange,提问作者Lyndz
相关产品推荐
相关产品推荐

