如何按Color列值变化拆分Pandas DataFrame为多个CSV(过滤误报0值)
点云DataFrame拆分解决方案
1. 核心思路
先识别出被前后各5个连续0值包围的0.5/1连续数据块,再将每个符合条件的块拆分为独立DataFrame,用于后续可视化。
2. 代码实现
步骤1:标记连续数据块
通过行的前后值变化,给每个连续的非0(0.5/1)数据块分配唯一ID:
import pandas as pd import numpy as np # 假设点云数据存储在df中 # 标记非0颜色类型,0值设为NaN df['color_type'] = df['Color'].where(df['Color'].isin([0.5, 1]), np.nan) # 生成块ID:当颜色类型变化或从0切换为非0时,创建新块 df['block_id'] = (df['color_type'].isna() != df['color_type'].shift(1).isna()) | \ (df['color_type'] != df['color_type'].shift(1)) df['block_id'] = df['block_id'].cumsum()
步骤2:筛选符合条件的有效块
检查每个非0块的前后是否存在连续5个0值,保留符合要求的块:
# 按块ID分组,提取所有非0块 non_zero_blocks = df[df['color_type'].notna()].groupby('block_id') valid_clusters = [] for _, block in non_zero_blocks: start_idx = block.index[0] end_idx = block.index[-1] # 检查块前是否有连续5个0 has_front_zero = (start_idx - 5 >= 0) and all(df.loc[start_idx-5:start_idx-1, 'Color'] == 0) # 检查块后是否有连续5个0 has_back_zero = (end_idx + 5 < len(df)) and all(df.loc[end_idx+1:end_idx+5, 'Color'] == 0) if has_front_zero and has_back_zero: valid_clusters.append(block)
步骤3:拆分后可视化(以Open3D为例)
每个valid_clusters中的元素都是独立的DataFrame,可直接用于点云可视化:
import open3d as o3d for idx, cluster_df in enumerate(valid_clusters): # 转换为Open3D点云格式 points = cluster_df[['X', 'Y', 'Z']].values # 映射颜色:0.5→红色,1→绿色 colors = cluster_df['Color'].map({0.5: [1,0,0], 1: [0,1,0]}).tolist() pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(points) pcd.colors = o3d.utility.Vector3dVector(colors) # 保存或可视化 o3d.io.write_point_cloud(f"point_cloud_cluster_{idx}.pcd", pcd) # o3d.visualization.draw_geometries([pcd]) # 直接可视化
3. 可选优化
如果存在短序列的误报0值(比如连续2个0插入非0块中),可先填充这类误报再进行块识别:
# 填充连续不超过2个的0值(可根据实际情况调整limit参数) df['Color'] = df['Color'].replace(0, np.nan).interpolate(limit=2, limit_direction='both').fillna(0)
内容的提问来源于stack exchange,提问作者Vishal Pendse
相关产品推荐
相关产品推荐

