python-记录一个多对多数据匹配,但是效率不高

import itertools
import os
import pandas as pd


def get_result(hope, list_input, used):
    """
    :param hope: # 期望相加所得参数
    :param list_input: # 所有数值
    :param used: # 已使用过列表,起始数据为空
    :return:
    """

    def generate_combination(items, length):
        for combination in itertools.combinations(items, length):
            result_generate = list(combination)
            # print(result)
            yield result_generate

    # 容差值,避免float计算过小
    epsilon = 0.001
    # 剔除大于目标值部分的列表内容不进行计算
    larger_list = [i for i in list_input if i > hope]
    step_1_list = list(set(list_input) - set(larger_list))
    # 剔除已使用过数据
    # print(used)
    step_1_list = list(set(step_1_list) - set(used))
    # 根据初步判断后的step_1_list,迭代每一种数据长度的可能性
    result = []
    for i in range(1, len(step_1_list) + 1):
        # print('当前判断长度:' + str(i))
        # 用迭代器  按照每种长度  生成每种可能
        calculate = generate_combination(items=step_1_list, length=i)
        # 循环迭代结果
        for x in calculate:
            # 对迭代器中每个元组求和
            if abs(sum(x) - hope) <= epsilon:
                result = x
                used = x
                # print('计算出', hope, ',组合是', result)
                # 计算出结果,则该
                break  # 如果计算出结果,则终止对迭代结果循环
        else:
            # print('无结果')
            continue  # 未计算出结果,继续对迭代结果循环
        break  # if True 则终止对所有长度可能的循环
    return hope, result, used


if __name__ == '__main__':
    # 准备填数文件和基础参数
    input_path = '数据求和匹配.xlsx'
    output_path = '数据求和匹配结果.xlsx'
    df_input = pd.DataFrame(columns=['求和标识', '求和列', '计算标识', '计算列'])
    # 若不存在前期文件,则新建模板用于计算
    if not os.path.exists(input_path):
        df_input.to_excel(input_path, index=False)
    os.system(input_path)
    # 根据df_input取数list1 list2
    df_input = pd.read_excel(input_path, dtype=str)
    df_input.fillna(0, inplace=True)
    list1 = df_input['计算列'].astype(float).tolist()
    list2 = df_input['求和列'].astype(float).tolist()
    print(sum(list1), sum(list2))
    # 开始运行,used装填已使用过数据 新建df数据用于汇总全部数据
    used = []
    df_total = pd.DataFrame()
    for i in list2:
        if i != 0:
            end = get_result(i, list1, used=used)
            sus_hope = end[0]  # 求和数据
            sus_result = end[1]  # 求和列表
            print(sus_hope, '计算结果', sus_result)
            sus_used = end[2]  # 已使用数据
            sus_used = used.extend(sus_used)
            # 组合hope和resu为结果数据
            df_division = pd.DataFrame(columns=['计算列'], data=sus_result)
            df_division['求和列'] = sus_hope
            df_total = pd.concat([df_division, df_total])
    df_total['求和列'] = df_total['求和列'].astype(str)
    df_total['计算列'] = df_total['计算列'].astype(str)
    add_df = df_input[['求和列', '求和标识']]
    df_total = pd.merge(df_total, add_df, on='求和列')
    cal_df = df_input[['计算列', '计算标识']]
    df_total = pd.merge(df_total, cal_df, on='计算列')
    print(df_total)
    df_result = pd.DataFrame(columns=['计算列', '计算标识', '求和标识', '求和列'])
    df_result = pd.concat([df_result, df_total])
    df_result.to_excel('result.xlsx', index=False)
    os.system('result.xlsx')
posted @ 2024-05-22 22:21  AZ26  阅读(65)  评论(0)    收藏  举报