接了个100元Python私活,失败了没搞定,复杂度极高的Excel数值计算

蚂蚁学Python

共 2295字,需浏览 5分钟

 ·

2021-11-22 19:33

一个有n+n^2+n^3...+n^n的Python私活订单

首先看下这个让我掉层头皮的数据,看上去很简单,很友好对吧?

1.需求

这个示例需要我根据悬赏者给定的某个指定值,比如0,来将这个数据集中所有可能的加和结果等于指定值对应的数值找出来,并将这些数值在旁边列标记为y,看上去也还可以不算太不友好,对吧?

接下来,先看下这组数据什么特点,先看下降序后的正数部分:

然后再看下升序后的负数部分

运行代码,你会发现还有很多0.01,这些数据告诉你,他的组合是千千万万的。

2. 代码部分

第一步,通过pandas的read_excel()方法就不能读取,报错信息显示这是一个比特字节数据类型,不支持导入,于是我就换了xlwings库里面range对象,来获取目标数据区域:

# 读取数据源
app = xw.App(visible=False,add_book=False)
workbook = app.books.open(r'demo.xlsx')
column_name = workbook.sheets[0].range('A1').value
all_data = workbook.sheets[0].range('A1').expand('down').value
s1 = pd.Series(all_data)

然后就到了业务部分,我一开始没想太多,就只是简单的认为把数据集每个数拿出来,遍历,然后和接下来的所有的数据做累积求和,直到等于指定值即可,然后自己写几个测试集看看效果即可,看下代码:

def df_modifier(df,num):
    for i in df.index:
        sum_val = df['data'][i]
        for j in df.index:
            sum_val += df['data'][j]
            if np.abs(sum_val)>num:
                sum_val += df['data'][j]
                print(sum_val)
                if sum_val == num:
                    df['marker'] = 'y'
    return df

测试集1:

num = 5
list1 = [1,2,3,4,5,6,-1]
df1 = pd.DataFrame(list1,columns=['data'])
df1 = df_modifier(df1)
df1

测试集2:

import numpy as np
num = 5
list2 = np.random.randint(-10,1000,size=1000)
df2 = pd.DataFrame(list2,columns=['data'])
df2['marker']='n'
df2 = df_modifier(df2)
df2[df2['marker']=='y']

测试集3:

import numpy as np
num = 5
list3 = np.arange(-1000,1000)
df3 = pd.DataFrame(list3,columns=['data'])
df3['marker']='n'
df3 = df_modifier(df3)

这里我的指定值是5,测试集1完美通过算法,但是测试集2和3,就没有任何结果,这是绝对不可接受的,因为肉眼都能看出有这样的组合,于是我就在想我的代码的逻辑是不是错了。

果然,我的逻辑都是基于所有的数累加是连续的序列的情况下,那么对于不连续的情况,比如5可以拆解为1,2,3,9,-9或者其他任何类似的组合,而且连续的求和有可能数值越来越大,根本无法满足条件就把电脑给卡死了,要知道他给我说的他的数据集能多到几万条。

那我就在想能有多少种情况来处理这个逻辑,那就逐步演化呗,首先直接找到相反数,是最简单的,而这种情况会有n个,而如果是找到有两个加和等于指定值,他的可能性是n^2个,类似的如果是三个就会有n^3个,以此类推直到n^n个,理论想通了,代码如何实现:

import itertools
nums = range(51)
for n in range(1, len(nums) + 1):
    for p in itertools.combinations(nums, n):
        if sum(p) == 41:
            print(*p)

我用了itertools里面的combinations方法,能够将所有的组合情况都给出,完美符合我的想法,然后事实很快打脸

代码运行到2520结果行的时候就卡住不动了,要知道我的电脑有12核,而且这个结果集我只提供了51条数据

姑且不去管最大值项外的其他项,看到图片里的51^51结果了吗,你觉得这个单子有法做吗?


如果你有更好的解法,联系ant_learn_python,这个100元的单子就是你的。


最后,推荐蚂蚁老师的Pandas入门课程:

https://ke.qq.com/course/4000628?tuin=2957a4ad

Pandas入门到实战案例48集


阅读原文也能到达目标页面

浏览 43
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报