接了個100元Python私活,失敗了沒搞定,復雜度極高的Excel數值計算
一個有n+n^2+n^3...+n^n的Python私活訂單
首先看下這個讓我掉層頭皮的數據,看上去很簡單,很友好對吧?
1.需求
這個示例需要我根據懸賞者給定的某個指定值,比如0,來將這個數據集中所有可能的加和結果等于指定值對應的數值找出來,并將這些數值在旁邊列標記為y,看上去也還可以不算太不友好,對吧?
接下來,先看下這組數據什么特點,先看下降序后的正數部分:

然后再看下升序后的負數部分

運行代碼,你會發(fā)現還有很多0.01,這些數據告訴你,他的組合是千千萬萬的。
2. 代碼部分
第一步,通過pandas的read_excel()方法就不能讀取,報錯信息顯示這是一個比特字節(jié)數據類型,不支持導入,于是我就換了xlwings庫里面range對象,來獲取目標數據區(qū)域:
#?讀取數據源
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)
然后就到了業(yè)務部分,我一開始沒想太多,就只是簡單的認為把數據集每個數拿出來,遍歷,然后和接下來的所有的數據做累積求和,直到等于指定值即可,然后自己寫幾個測試集看看效果即可,看下代碼:
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,就沒有任何結果,這是絕對不可接受的,因為肉眼都能看出有這樣的組合,于是我就在想我的代碼的邏輯是不是錯了。
果然,我的邏輯都是基于所有的數累加是連續(xù)的序列的情況下,那么對于不連續(xù)的情況,比如5可以拆解為1,2,3,9,-9或者其他任何類似的組合,而且連續(xù)的求和有可能數值越來越大,根本無法滿足條件就把電腦給卡死了,要知道他給我說的他的數據集能多到幾萬條。
那我就在想能有多少種情況來處理這個邏輯,那就逐步演化唄,首先直接找到相反數,是最簡單的,而這種情況會有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入門到實戰(zhàn)案例48集

閱讀原文也能到達目標頁面
