我的目标是仅过滤构成销售额的前 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%?
答案 0 :(得分: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%,产生一个布尔数组.shift(1, fill_value=False)
) 以还包括第一个值,该值大于/等于总和的 80% 并用 False
填充(否则第一个值将用 { {1}})