基于多方向3D剖面分析的机载LiDAR聚类代码报错求助
机载LiDAR多方向剖面分析聚类报错问题
问题描述
用多方向剖面分析处理机载LiDAR数据时,执行聚类操作报错。原因是剖面分析的输出被错误处理为一维数据,而KMeans聚类要求输入至少为二维数组(样本×特征的结构)。
相关代码
多方向剖面分析函数
import numpy as np from sklearn.cluster import KMeans def multidirectional_profile_analysis(las_file_path, directions=[0, 45, 90, 135, 180, 225, 270, 315]): # 需补充从las文件读取x,y,z坐标的逻辑,示例:x,y,z = read_lidar_points(las_file_path) profile_data = [] for direction in directions: radian = np.radians(direction) cos_angle = np.cos(radian) sin_angle = np.sin(radian) profile_x = x * cos_angle + y * sin_angle profile_y = x * -sin_angle + y * cos_angle profile_z = z # 将当前方向的三个特征组合为N×3的二维数组,每行对应一个点的剖面特征 profile = np.column_stack((profile_x, profile_y, profile_z)) profile_data.append(profile) return profile_data
原报错聚类代码
profile_data = multidirectional_profile_analysis("your_las_file.las") a = np.asarray(profile_data) cluster_centers = [] for i in range(len(a)): # 错误:直接对三维数组取极值并筛选,导致输出一维数组 min_val = np.min(a[i]) max_val = np.max(a[i]) in_range_points = np.asarray(a[i][(a[i] >= min_val) & (a[i] <= max_val)]) if len(in_range_points) >= 10: kmeans = KMeans(n_clusters=8) cluster_centers.append(kmeans.fit_predict(in_range_points))
报错信息
ValueError Traceback (most recent call last) <ipython-input-45-a206a3d15e5f> in <cell line: 4>() 13 if len(in_range_points) >= 10: 14 kmeans = KMeans(n_clusters=8) ---> 15 cluster_centers.append(kmeans.fit_predict(in_range_points)) 3 frames /usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py in fit_predict(self, X, y, sample_weight) 1031 Index of the cluster each sample belongs to. 1032 """ -> 1033 return self.fit(X, sample_weight=sample_weight).labels_ 1034 1035 def predict(self, X, sample_weight=None): /usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py in fit(self, X, y, sample_weight) 1415 self._validate_params() 1416 -> 1417 X = self._validate_data( 1418 X, 1419 accept_sparse="csr", /usr/local/lib/python3.10/dist-packages/sklearn/base.py in _validate_data(self, X, y, reset, validate_separately, **check_params) 563 raise ValueError("Validation should be done on X, y or both.") 564 elif not no_val_X and no_val_y: ---> 565 X = check_array(X, input_name="X", **check_params) 566 out = X 567 elif no_val_X and not no_val_y: /usr/local/lib/python3.10/dist-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator, input_name) 900 # If input is 1D raise error 901 if array.ndim == 1: ---> 902 raise ValueError( 903 "Expected 2D array, got 1D array instead:\narray={}.\n" 904 "Reshape your data either using array.reshape(-1, 1) if " ValueError: Expected 2D array, got 1D array instead: array=[491883.2864686 491883.2924686 491883.2934686 ... 1463.268 1463.365 1463.454 ]. Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.
问题分析与修复
核心问题
- 原代码将剖面数据存储为
(profile_x, profile_y, profile_z)三元组,转成数组后形状为(8,3,N)(8为方向数,3为特征数,N为点数量),维度结构不符合聚类要求。 - 聚类循环中,极值计算和筛选操作将三维数据扁平化,最终得到一维数组,触发KMeans的维度校验报错。
修复后的聚类代码
profile_data = multidirectional_profile_analysis("your_las_file.las") cluster_labels_list = [] cluster_centers_list = [] for profile in profile_data: # 按高度筛选树冠点(可根据需求调整分位数阈值) z_min = np.percentile(profile[:,2], 10) z_max = np.percentile(profile[:,2], 90) filtered_points = profile[(profile[:,2] >= z_min) & (profile[:,2] <= z_max)] if len(filtered_points) >= 10: kmeans = KMeans(n_clusters=8, random_state=42) cluster_labels = kmeans.fit_predict(filtered_points) cluster_labels_list.append(cluster_labels) cluster_centers_list.append(kmeans.cluster_centers_)
关键修改点
- 调整剖面数据组织:用
np.column_stack将每个方向的三个特征合并为N×3的二维数组,每行对应一个点的完整剖面特征。 - 修正筛选逻辑:针对高度维度筛选有效点,避免扁平化整个三维数据,确保输入KMeans的是标准的二维样本数组。
- 增加
random_state参数,保证聚类结果可复现。
内容的提问来源于stack exchange,提问作者survey08
相关产品推荐
相关产品推荐

