最近站点去重,密集站点抽稀

最近站点去重,密集站点抽稀

工作中常常遇到多个站点密集在一起,如ABCD,A最近的是B,B最近的是C,需要将这些站点进行抽稀处理。经过几翻折腾,终于搞定,处理工具如下: 最近站点去重,密集站点抽稀_第1张图片
假设已有以下数据:
最近站点去重,密集站点抽稀_第2张图片

import pandas as pd
from math import (pi, radians, sin, cos, asin, sqrt, degrees, atan2, ceil)

#定义距离计算方法
def calculate_distance(lon1, lat1, lon2, lat2):
    lon1, lat1, lon2, lat2 = map(radians, [float(lon1), float(lat1), float(lon2), float(lat2)])
    d_lon, d_lat = lon2 - lon1, lat2 - lat1
    am = sin(d_lat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(d_lon / 2) ** 2
    distance = 2 * asin(sqrt(am)) * 6371229
    return float('%.4f' % distance)


def run_site_filter():
    df = pd.read_excel(path_in, sheet_name='密集站点抽稀处理')

    # 定义列表集,用于存放删除了哪些站点
    temp_del_all = []

    # 程序需要无限循环操作,直到将需要的距离范围内最近的站点全部清除为止。
    m = 1
    while True:
        # 定义处理过程的表df_x
        df_x = []
        for numb_a, lon_a, lat_a, info_a in zip(df.编号, df.经度, df.纬度, df.信息1):
            for numb_b, lon_b, lat_b, info_b in zip(df.编号, df.经度, df.纬度, df.信息1):
                if numb_a != numb_b:
                    temp_distance = calculate_distance(lon_a, lat_a, lon_b, lat_b)
                    df_x.append([numb_a, info_a, numb_b, info_b, temp_distance])
                    
        # 每一次的计算结果表,此表后面还要用到
        df_x = pd.DataFrame(df_x) 
        df_x['rank'] = df_x.groupby([0]).rank(method='dense', ascending=1)[4]  # 按基站名和距离来排序
        df_x_rank_3 = df_x[df_x['rank'] <= 3] 
        df_x_rank_3_mean = df_x_rank_3.groupby(0)[4].mean()  # 每一个站点最近3处点的平均距离,用于空间考虑,尽量保留空间位置较稀疏的点位。

        distance_values_min = df_x[4].min()  # df_x[4]代表temp_distance列,筛选出距离最小的值
        df_x_min = df_x[df_x[4] == distance_values_min]

        # 如果距离小于300米,就继续进行数据处理,一直到没有小于300米的为止。
        if distance_values_min <= float(filter_distance_value):
            # 处理过程中要保留谁?要删掉谁?需要在模板中给每个站点的一个权值,根据权值来判断;
            temp_del = []
            for x, x_info, y, y_info in zip(df_x_min[0], df_x_min[1], df_x_min[2], df_x_min[3]):
                if x_info > y_info:
                    temp_del.append(y)
                elif x_info < y_info:
                    temp_del.append(x)
                elif x_info == y_info:
                    if df_x_rank_3_mean[x] < df_x_rank_3_mean[y]:
                        temp_del.append(x)
                    elif df_x_rank_3_mean[x] > df_x_rank_3_mean[y]:
                        temp_del.append(y)
                    elif df_x_rank_3_mean[x] == df_x_rank_3_mean[y]:
                        if (x not in temp_del) & (y not in temp_del):
                            temp_del.append(y)
                        elif (x in temp_del) & (y not in temp_del):
                            temp_del.append(x)
                        elif (x not in temp_del) & (y in temp_del):
                            temp_del.append(y)
                        elif (x in temp_del) & (y in temp_del):
                            temp_del.append('no,all in temp_del')
                        else:
                            temp_del.append('其他情况,需人工分析')

            temp_del_remove_duplicates = list(set(temp_del))
            temp_del_all.append(temp_del_remove_duplicates)  # 将要删除的站点放入列表中
            # 删除df0表中不需要的站点
            for i in temp_del_remove_duplicates:
                df = df[df['编号'] != i]
            df = pd.DataFrame(df)  # 得到删除后的、剩余的站点列表,df表第一次处理完成。

            temp_view = ' Please wait' + '\t' + str(m) + '\t' + str(distance_values_min)
            print(temp_view)

        else:
            print("用户指定距离范围内的运算已完成!")
            break

        m += 1

    # 输出要删除的站点清单
    temp_del_all = pd.DataFrame(temp_del_all)
    file_del_path = r'D:\xxx删除的站点.xlsx'
    temp_del_all.to_excel(file_del_path, index=None, encoding='gbk')

    # 输出最终要保留下来的站点清单
    file_save_path = r'D:\xxx保留的站点.xlsx'
    df.to_excel(file_save_path, index=None, encoding='gbk')
    print("运算全部完成,请查看输出的EXCEL文件")


if __name__ == '__main__':
    path_in = r'D:\经纬度信息表.xlsx'
    filter_distance_value = 300  # 指定需要处理的距离,米
    run_site_filter()

你可能感兴趣的:(python,运维,网络,自动化)