我有跨不同区域的汇总作业的数据,按区域的默认交付半径分组,因此如下所示
radius_km num_jobs
3.0 37745
5.0 327963
6.0 259885
7.0 145021
8.0 128145
9.0 280185
10.0 790295
11.0 72166
12.0 1872242
13.0 152221
14.0 202767
15.0 477996
16.0 33438
20.0 17098我正在尝试将不同的半径组绑定在一起,以便现在有X个组(保持半径连续性,例如3-5 5km,6-10 5km),每个组中的num_jobs尽可能相等。
我一直在尝试使用pd.cut或pd.qcut,但我似乎无法从中获得我想要的东西。
我的预期结果如下所示:
radius_km_bin num_jobs
3.0 - 9.0 x
10.0 - 12.0 y
13.0 - 20 z其中x~y~z
我在这里选择的范围只是为了说明格式,而不是实际所需的范围。
发布于 2019-08-20 08:20:16
这里有一种可怕的老套方法,我几乎不好意思分享,但它完成了工作(假设你把它分成3个箱子),希望它能让你知道如何做it..this是一个简单的优化问题,但因为你本质上是优化如何对你的df切片,索引是整数,这变成了一个整数编程问题,这在python中并不容易
import pandas as pd
import numpy as np
res=np.empty([0,3]) #empty np array
df = pd.read_csv('test.csv') #read in df
new = pd.DataFrame(columns=['radius_km_bin','num_jobs']) #output df
num_jobs = df.num_jobs.values #assign values to array
for i in range(len(num_jobs)-2): #first split in array
for j in range(i+1,len(num_jobs)-1): #second split in array
diff1=abs(sum(num_jobs[:i])-sum(num_jobs[i:j])) #diff between 1st/2nd chunk
diff2=abs(sum(num_jobs[i:j])-sum(num_jobs[j:])) #diff between 2nd/3rd chunk
tmp = np.array([[i,j,diff2+diff1]]) #combined error
res = np.append(res,tmp,axis=0) #save i,j,error to array
i,j = int(res[res[:,2]==min(res[:,2]),0][0]),int(res[res[:,2]==min(res[:,2]),1][0]) #find i,j corresponding to min error, convert to int for indexing
new['radius_km_bin'] = [' '.join([str(kms[0]),'-',str(kms[0:i][-1])]),' '.join([str(kms[i]),'-',str(kms[i:j][-1])]),' '.join([str(kms[j]),'-',str(kms[-1])])] #join kms into string for output dataframe
new['num_jobs'] = [sum(df['num_jobs'][0:i]),sum(df['num_jobs'][i:j]),sum(df['num_jobs'][j:])] #sum num_jobs within the chunks输出:
radius_km_bin num_jobs
0 3 - 10 1969239
1 11 - 12 1944408
2 13 - 20 883520我相信有更好的方法可以做到这一点,但希望这能将您引向这个方向
编辑-一种更好的方式:
from scipy.optimize import minimize
def diffs(x):
diff1=abs(sum(num_jobs[:int(x[0])])-sum(num_jobs[int(x[0]):int(x[1])]))
diff2=abs(sum(num_jobs[int(x[0]):int(x[1])])-sum(num_jobs[int(x[1]):]))
diff3=abs(sum(num_jobs[:int(x[0])])-sum(num_jobs[int(x[1]):]))
return sum([diff1,diff2,diff3])
r = minimize(diffs,x,method='Powell')
i,j = int(r.x[0]),int(r.x[1])这样我就得到了同样的答案
https://stackoverflow.com/questions/57564703
复制相似问题