前 80% 的销售额百分比

时间:2021-01-29 09:21:33

标签: python

我的目标是仅过滤构成销售额的前 80% 的产品

我总共有 100 种产品,总销售额为 15000,所以要找出我正在做的产品的销售额百分比是多少

product_dict = {}
for product in products:
    percent_from_sale = product.quantity / total_quantity * 100
    product_dict[product] = percent_from_sale

因此,在此之后,我对关键产品进行了 dict,价值是该产品销售的百分比,但如何仅过滤前 80%?

4 个答案:

答案 0 :(得分:1)

  1. 您可以将 product_dict{product:sales} 转换为 sales_list[(sales, product)]
sales_list=[(v,k) for k,v in product_dict.items()]

按销售额倒序(从高到低)对sales_list进行排序

sales_list.sort(reverse=True, key=lambda x:x[0])

然后迭代它计算累积和,直到它小于 80

cumulative_sale = 0
top_80_products = {}
for sale, product in sales_list:
    top_80_products[product] = sale
    cumulative_sale += sale
    if cumulative_sale >= 80:
        break

答案 1 :(得分:1)

您可以定义generator function,它会产生个元素,直到累积总和达到某个限制:

def iter_until(src, limit, key):
    cumulative_sum = 0
    for element in src:
        yield element
        cumulative_sum += key(element)
        if cumulative_sum >= limit:
            break

让我们生成类似于您的输入:

from collections import namedtuple
from random import shuffle

product = namedtuple("product", "name quantity")
total_quantity = 15000
products = [product(f"product{i}", total_quantity // (2 ** i)) for i in range(1, 101)]
shuffle(products)

现在您可以迭代生成器函数。您可以创建销售额前 80% 的列表

sorted_products = sorted(products, key=lambda x: x.quantity, reverse=True)
top_80_percent = list(iter_until(sorted_products, total_quantity * 0.8, lambda x: x.quantity))

您可以创建 dict (您在代码形式问题中尝试做的事情)

sorted_products = sorted(products, key=lambda x: x.quantity, reverse=True)
top_80_percent = {p.name: p.quantity for p in iter_until(sorted_products, total_quantity * 0.8, lambda x: x.quantity)}

答案 2 :(得分:1)

类似于@lllrnr101 的回答,但在排序上略有不同。

Use 可以使用 (product, percent) 函数通过第二个参数(百分比)获取已排序的元组列表 operator.itemgetter。 然后迭代这些对,直到达到累计销售额的 80%。

import operator

product_dict = {
    product: percent
    for product in products
}

sorted_items = sorted(
    product_dict.items(),
    key=operator.itemgetter(1),
    reverse=True,
)

cumulative = 0
top_80_sales = {}
for product, percent in sorted_items:
    if cumulative < 0.8:
        top_80_sales[product] = percent
        cumulative += percent
    else:
        break

答案 3 :(得分:1)

如果可以使用pandas或numpy,就可以大幅降低所需的LOC并提高性能(尤其是对于大量产品)。

要从 pandas 开始,首先将其导入并从您的数据中创建一个数据框(从 Olvin Roght 获取的示例数据创建):

from collections import namedtuple
from random import shuffle

import pandas as pd

# create sample data
product = namedtuple("product", "name quantity")
total_quantity = 15000
products = [product(f"product{i}", total_quantity // (2 ** i)) for i in range(1, 101)]
shuffle(products)

# make into dataframe
prods = pd.DataFrame(products)

现在按数量对数据框进行排序:

prods_sort = prods.sort_values(by='quantity', ascending=False)

并获得前 80% 的产品:

top_products = prods_sort[
    ~prods_sort.loc[:, 'quantity'].cumsum().ge(
        prods_sort.loc[:, 'quantity'].sum() * .8
    ).shift(1, fill_value=False)

print(top_products)

# Out:
        name  quantity
40  product1      7500
94  product2      3750
65  product3      1875

我在这里做什么:

  • 获取数量的累计总和
  • 检查累积总和大于/等于 (.ge(...)) 的总和的 80%,产生一个布尔数组
  • 将其移动 1 (.shift(1, fill_value=False)) 以还包括第一个值,该值大于/等于总和的 80% 并用 False 填充(否则第一个值将用 { {1}})
  • 用这个布尔数组索引排序后的产品,得到占总数量 80% 的产品