使用条件和排名进行分组的 Python/Pandas 实现
Posted
技术标签:
【中文标题】使用条件和排名进行分组的 Python/Pandas 实现【英文标题】:Python/Pandas implementation for grouping with a condition and ranking 【发布时间】:2019-05-26 12:36:03 【问题描述】:我想按邮政编码分组并形成褶皱,但如果达到 30000,它应该形成另一辆卡车。我无法申请分组并对其进行排名。可能需要按升序对重量进行排序以形成正确的卡车。任何帮助将不胜感激。
我有以下数据:
Load No. Zip Code Pounds
1 50507 20000
2 50507 8000
3 50507 5000
4 60001 28000
5 60001 30000
6 60001 2000
7 60001 4000
8 60002 20000
9 60002 18000
10 60002 13000
输出:
Load No. Zip Code Pounds Truck Total Weight
1 50507 20000 1 28000
2 50507 8000 1 28000
3 50507 5000 2 5000
4 60001 28000 3 30000
5 60001 30000 5 2000
6 60001 2000 3 30000
7 60001 4000 4 4000
8 60002 20000 6 20000
9 60002 18000 7 18000
10 60002 13000 8 13000
我已经对数据框进行了排序: data=data.sort_values(by=['Zip Code','Pounds'])
还尝试按邮政编码分组,但未能放入条件(> 20000)以形成密集排名: data['总重量'] = data.groupby('邮政编码')['磅'].transform(sum)
【问题讨论】:
欢迎使用 ***,请发布代码 sn-p 显示您的代码以及您尝试过的内容。 我已经添加了我编码的内容,但是我不知道如何通过分组来求和和制造卡车。如果您能提供帮助,将不胜感激。谢谢! 【参考方案1】:我想我看到了您想要完成的工作,所以我完成了您正在寻找的部分内容,剩下的留给您自己决定。这个问题中最困难的部分似乎是智能地分配负载以最大化卡车空间。拆分是没有问题的,但不是只检查负载是否小于30,000那么简单。
首先,一种在卡车之间智能分配负载的方法:
def build_trucks(sorted_loads):
load_copy = np.array(sorted_loads)
truck_max = 30000
# check if any loads are > truck_max and split them into bins that sum to the load
while len(load_copy) > 0:
truck = []
truck_load = 0
for i, load in enumerate(load_copy):
if truck_load + load <= truck_max:
truck.append(i)
truck_load += load
yield load_copy[truck]
load_copy = np.delete(load_copy, truck)
你没有提到任何负载是否会超过 30,000,所以我离开了而不是不完整。这本身就是一个有趣的问题(将 45,000 分成两个负载:30,000 和 15,000,将 65,000 分成两个 30,000 和 5,000)。我针对一些测试运行了这个,包括你的:
print(list(build_trucks(np.array([20000, 8000, 5000]))))
print(list(build_trucks(np.array([30000, 28000, 4000, 2000]))))
print(list(build_trucks(np.array([20000, 18000, 13000]))))
print(list(build_trucks(sorted(np.array([25000, 1000, 1000, 4000, 5500]), reverse=True))))
哪个输出:
[array([20000, 8000]), array([5000])]
[array([30000]), array([28000, 2000]), array([4000])]
[array([20000]), array([18000]), array([13000])]
[array([25000, 4000, 1000]), array([5500, 1000])]
为了看看它的行为如何,我跑了:
grp = data.groupby('zip')
for i, g in grp:
print(g.sort_values('pounds', ascending=False))
print()
print(list(build_trucks(g['pounds'])))
print()
其中data
是您提供的原始数据的DataFrame。希望问题的其余部分对您来说很明显。如果没有,请随时询问,我会尽力提供帮助(我留下了很多不完整的内容,因为这对你来说是一个很好的学习问题,但我不想花太多自己的时间在上面)。可能有很多方法可以做到这一点,这是我看到的第一种方式。我还想到了一种递归方式来做到这一点,可能有效也可能无效。
【讨论】:
以上是关于使用条件和排名进行分组的 Python/Pandas 实现的主要内容,如果未能解决你的问题,请参考以下文章