You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python合并站点DataFrame、K-Means聚类及结果可视化实现方法

需求可行性判断

该需求完全可实现。核心实现逻辑是先对齐两类站点的时序观测数据,构造站点配对的多维度特征,再通过K-Means聚类划分特征相似的站点组,最终筛选出同组内关联度最高的空气-土壤站点对作为匹配结果,全流程可通过Python数据科学生态完成。

具体操作步骤

1 安装依赖库

先安装流程需要的第三方库,执行命令:
pip install pandas numpy scikit-learn matplotlib seaborn

2 数据预处理与合并

首先规范两个数据集的格式,按时间维度对齐数据,生成所有可能的空气-土壤站点配对组合:

import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import seaborn as sns

# 加载/构造空气站点数据集(替换为你实际的读入代码即可)
air_data = pd.DataFrame({
    'time': ['00:06:00','00:06:00','00:06:00','00:06:00',
             '00:07:00','00:07:00','00:07:00','00:07:00',
             '00:08:00','00:08:00','00:08:00','00:08:00',
             '00:09:00','00:09:00','00:09:00','00:09:00'],
    'Air Station Code': ['St.1','St.2','St.3','St.4']*4,
    'Humidity': [20,4,16,38,10,40,10,46,28,14,5,11,61,23,35,31],
    'Temperature': [10,15,21,8,18,4,13,11,9,22,40,10,35,29,12,7]
}).set_index('time')

# 加载/构造土壤站点数据集(替换为你实际的读入代码即可)
soil_data = pd.DataFrame({
    'time': ['00:06:00','00:06:00','00:07:00','00:07:00',
             '00:08:00','00:08:00','00:09:00','00:09:00'],
    'Soil Station Code': ['St.1','St.2']*4,
    'Soil Moisture': [21,40,10,47,18,34,16,30]
}).set_index('time')

# 统一列名格式,去除多余空格
air_data.columns = [c.strip() for c in air_data.columns]
soil_data.columns = [c.strip() for c in soil_data.columns]

# 按时间维度做内连接,生成同时间点的所有站点配对
merged = air_data.reset_index().merge(
    soil_data.reset_index(),
    on='time',
    how='inner'
)

3 构造聚类特征并执行K-Means聚类

按站点对分组,提取统计特征、时序相关性特征作为聚类输入,标准化后完成聚类:

# 按空气站-土壤站配对分组,构造聚类特征
pair_features = merged.groupby(['Air Station Code', 'Soil Station Code']).agg(
    humid_mean=('Humidity', 'mean'),
    temp_mean=('Temperature', 'mean'),
    soil_moist_mean=('Soil Moisture', 'mean'),
    humid_std=('Humidity', 'std'),
    temp_std=('Temperature', 'std'),
    soil_moist_std=('Soil Moisture', 'std'),
    # 计算空气站指标与土壤湿度的时序相关性
    corr_humid_soil=('Humidity', lambda x: x.corr(merged.loc[x.index, 'Soil Moisture'])),
    corr_temp_soil=('Temperature', lambda x: x.corr(merged.loc[x.index, 'Soil Moisture']))
).reset_index()

# 特征标准化,消除量纲影响
feature_cols = ['humid_mean','temp_mean','soil_moist_mean','humid_std','temp_std','soil_moist_std','corr_humid_soil','corr_temp_soil']
X = pair_features[feature_cols].values
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 用肘部法则确定最优簇数,示例数据中土壤站共2个,最优k为2
inertia = []
k_range = range(1, len(pair_features)+1)
for k in k_range:
    km = KMeans(n_clusters=k, random_state=42, n_init='auto')
    km.fit(X_scaled)
    inertia.append(km.inertia_)

# 执行聚类,簇数设置为与土壤站点总数一致即可
kmeans = KMeans(n_clusters=2, random_state=42, n_init='auto')
pair_features['cluster'] = kmeans.fit_predict(X_scaled)

# 提取最终匹配结果:同簇下相关性最高的站点对为匹配对
match_result = pair_features.sort_values(
    by=['cluster', 'corr_humid_soil', 'corr_temp_soil'],
    ascending=[True, False, False]
).groupby('Soil Station Code').first().reset_index()[['Soil Station Code', 'Air Station Code', 'cluster']]
print("站点匹配结果:")
print(match_result)

4 结果可视化

通过三类图表分别展示聚类参数选择、聚类分布、匹配站点的时序一致性:

plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决中文显示问题,可根据自己系统调整
plt.figure(figsize=(12,5))

# 子图1:肘部法则结果
plt.subplot(1,2,1)
plt.plot(k_range, inertia, 'bo-')
plt.xlabel('聚类簇数k')
plt.ylabel('簇内平方和')
plt.title('肘部法则确定最优k值')

# 子图2:聚类散点分布
plt.subplot(1,2,2)
sns.scatterplot(data=pair_features, x='humid_mean', y='soil_moist_mean', hue='cluster', style='Soil Station Code', s=150)
for _, row in pair_features.iterrows():
    plt.text(row.humid_mean+0.5, row.soil_moist_mean+0.5, f"空气站:{row['Air Station Code']}\n土壤站:{row['Soil Station Code']}", fontsize=8)
plt.xlabel('平均湿度')
plt.ylabel('平均土壤湿度')
plt.title('站点对聚类结果分布')
plt.tight_layout()
plt.show()

# 匹配站点时序趋势对比图
plt.figure(figsize=(12,5))
for i, soil_st in enumerate(match_result['Soil Station Code'].unique()):
    air_st = match_result[match_result['Soil Station Code']==soil_st]['Air Station Code'].iloc[0]
    plt.subplot(1,2,i+1)
    air_series = air_data[air_data['Air Station Code']==air_st][['Humidity','Temperature']]
    soil_series = soil_data[soil_data['Soil Station Code']==soil_st][['Soil Moisture']]
    plot_df = air_series.join(soil_series)
    plt.plot(plot_df.index, plot_df['Humidity'], label='空气湿度', marker='o')
    plt.plot(plot_df.index, plot_df['Temperature'], label='空气温度', marker='s')
    plt.plot(plot_df.index, plot_df['Soil Moisture'], label='土壤湿度', marker='^')
    plt.title(f'匹配对:土壤站{soil_st} <-> 空气站{air_st}')
    plt.legend()
    plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
注意事项
  • 实际使用时如果土壤站点总数为N,可直接将K-Means聚类簇数设为N,也可结合肘部法则、轮廓系数法校验最优簇数,避免主观设置的偏差。
  • 如果手头有站点的经纬度、海拔等空间属性,可将空间距离作为特征加入聚类输入,能大幅提升站点匹配的准确率。
  • 聚类前必须对所有输入特征做标准化处理,避免不同量纲的特征(如温度、湿度、土壤湿度数值范围差异大)主导聚类结果,导致匹配错误。
  • 如果时序数据时间跨度更长,可额外加入时序相关系数、变化趋势一致性等特征,进一步提升匹配精度。

内容的提问来源于stack exchange,提问作者user16603056

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 15:57:17