我有5周的产品和商店组合销售数据。在5周内,前三个可以进行促销活动。第一个是促销,第二个或第三个或全部三个,或者没有一个是促销。所以总共有8个条件。现在我想用循环计算python中的移动平均类事物。简单来说,我将根据支票计算平均值,如果特定周是促销,则以不同方式计算。 (每周循环的开始和结束如下。
表1
week week week week week
1 2 3 4 5
loop_start_1 1 1 1 2 3
loop_end_1 3 4 5 5 5
loop_start_2 1 1 2 3 4
loop_end_2 2 3 4 5 5
对于第1周,我将取第1周,第2周和第3周的平均值,但对于第2周,我将取1,2,3,4的平均值,依此类推。现在如果一周是促销,这种情况会改变。输入我的数据:
表2
prod_id store_id sales_week1 sales_week2 sales_week3 sales_week4 sales_week5 promo_1 promo_2 promo_3 promo_4 promo_5
12345 22222 40 44 50 20 21 0 0 0 0 0
12346 22222 82 85 51 72 97 1 0 0 0 0
12347 22222 74 113 31 25 19 0 1 0 0 0
12348 22222 74 105 195 216 142 0 0 1 0 0
12349 22222 78 81 23 10 67 1 1 0 0 0
12243 22222 159 190 223 137 89 0 1 1 0 0
12240 22222 591 457 556 278 726 1 0 1 0 0
22240 22222 76 49 84 132 121 1 1 1 0 0
最多可以有8种不同的组合。根据前三个星期我们有哪些促销活动。我希望如下(基于下面提到的循环的移动平均值)
表3
prod_id store_id sales_week1 sales_week2 sales_week3 sales_week4 sales_week5 promo_1 promo_2 promo_3 promo_4 promo_5
12345 22222 44.6667 38.5 35 33.75 30.3333 0 0 0 0 0
12346 22222 82 69.3333 76.25 76.25 73.3333 1 0 0 0 0
12347 22222 52.5 113 37.25 25 25 0 1 0 0 0
12348 22222 89.5 131.6667 195 154.3333 179 0 0 1 0 0
12349 22222 79.5 79.5 33.3333 33.3333 33.3333 1 1 0 0 0
12243 22222 159 206.5 206.5 113 113 0 1 1 0 0
12240 22222 591 367.5 556 487 502 1 0 1 0 0
22240 22222 62.5 69.6667 66.5 126.5 126.5 1 1 1 0 0
现在我有一个虚拟代码(8个条件),我想根据促销条件转换为循环。如果条件不要写这么多。请提前帮助谢谢。
if promo_1 =1 then:
sales_new[1]=sales_old[1]
sales_new[2]=average(sales_old[2],sales_old[3],sales_old[4])
sales_new[3]=avergae(sales_old[2],sales_old[3],sales_old[4],sales[5])
sales_new[4]=avergae(sales_old[2],sales_old[3],sales_old[4],sales[5])
sales_new[5]=avergae(sales_old[3],sales_old[4],sales[5])
if promo_2 =1 then:
sales_new[1]=average(sales_old[1],sales_old[3])
sales_new[2]=sales_old[2]
sales_new[3]=avergae(sales_old[1],sales_old[3],sales_old[4],sales[5])
sales_new[4]=avergae(sales_old[3],sales_old[4],sales[5])
sales_new[5]=avergae(sales_old[3],sales_old[4],sales[5])
if promo_3 =1 then:
sales_new[1]=average(sales_old[1],sales_old[2])
sales_new[2]=average(sales_old[1],sales[2],sales[4]
sales_new[3]=sales_old[3]
sales_new[4]=avergae(sales_old[2],sales_old[4],sales[5])
sales_new[5]=avergae(sales_old[4],sales[5])
if promo_1 =1 and promo_2=1 then:
sales_new[1]=average(sales_old[1],sales_old[2])
sales_new[2]=average(sales_old[1],sales_old[2])
sales_new[3]=average(sales_old[3],sales_old[4],sales_old[5])
sales_new[4]=average(sales_old[3],sales_old[4],sales_old[5])
sales_new[5]=average(sales_old[3],sales_old[4],sales_old[5])
if promo_2 =1 and promo_3=1 then:
sales_new[1]=sales_old[1]
sales_new[2]=average(sales_old[2],sales_old[3])
sales_new[3]=average(sales_old[2],sales_old[3])
sales_new[4]=average(sales_old[4],sales_old[5])
sales_new[4]=average(sales_old[4],sales_old[5])
if promo_1 =1 and promo_3=1 then:
sales_new[1]=sales_old[1]
sales_new[2]=average(sales_old[2],sales_old[4])
sales_new[3]=sales_old[3]
sales_new[4]=average(sales_old[2],sales_old[4],sales_old[5])
sales_new[4]=average(sales_old[4],sales_old[5])
if promo_1 =1 and promo_2=1 and promo_3=1 then:
sales_new[1]=average(sales_old[1],sales_old[2])
sales_new[2]=average(sales_old[1],sales_old[2],sales_old[3])
sales_new[3]=average(sales_old[2],sales[3])
sales_new[4]=average(sales_old[4],sales_old[5])
sales_new[5]=average(sales_old[4],sales_old[5])
if promo_1 =0 and promo_2=0 and promo_3=0 then:
sales_new[1]=average(sales_old[1],sales_old[2],sales_old[3])
sales_new[2]=average(sales_old[1],sales_old[2],sales_old[3],sales_old[4])
sales_new[3]=average(sales_old[1],sales_old[2],sales_old[3],sales_old[4],sales_old[5])
sales_new[3]=average(,sales_old[2],sales_old[3],sales_old[4],sales_old[5])
sales_new[5]=average(sales_old[3],sales_old[4],sales_old[5])
商家规则
在本节中,我提供了业务规则,以阐明我的代码的要求。
在最高级别,我的目标是计算销售的移动平均值。我通过一个脚本计算新的销售数据(包含这些平均值)来自" old" (原始)数据。
对于未提升的任何一周,我们会考虑 loop_start_1和loop_end_1 ,但如果一周提升,我们会考虑 loop_start_2和loop_end_2
一个规定是每个新的周销售数据 - 默认 - 从旧周销售数据的子集中派生。这在表1中指定。例如,第1周的新销售数据(默认情况下)是根据未提升周数的第1-3周的旧销售数据计算得出的。
然而,每周可能会或可能不会是"促销"这一周,这将影响该周的旧销售数据是否可用于计算新的销售数据。 这会覆盖表1 loop_start_1和loop_end_1 指定的内容。对于促销活动,我们会考虑表1中的 loop_start_2和loop_end_2 ,特别是:
例如,如果第1周正在推广,那么我们需要执行以下操作:
计算week_1_new = avg(week_1_old)
。
计算week_2_new = avg(week_2_old, week_3_old, week_4_old)
另一方面,如果第1周和第2周都在推广,那么请考虑我们如何计算第1周的新销售数据:
week_1_new = avg(week_1_old, week_2_old)
另一方面,如果所有第1周和第3周都在推广,那么请考虑我们如何计算第1周的新销售数据:
week_1_new = avg(week_1_old)
(loop_start_2和loop_end_2)仅在第一周的1-2周内进行推广。我们从不在产品升级时添加销售额,而不提升产品的那一周。因为这会夸大平均值。week_2_new = avg(week_2_old,week_4_old)
((1-4中的loop_start_1和loop_end_1仅提升2和4) week_3_new = avg(week_3_old)
另一方面,如果所有第1周到第3周都在推广,那么请考虑我们如何计算第1周的新销售数据:
week_1_new = avg(week_1_old,week_2_old)
( loop_start_2和loop_end_2 )week_2_new = avg(week_1_old,week_2_old,week_4_old)
as( loop_start_2和loop_end_2 )表示第1-3周将被考虑用于第2周的推广weeeks week_3_new = avg(week_2_old,week_3_old)
as( loop_start_2和loop_end_2 )表示第2-4周。但在2,3,4中只有2和3被提升。所以只需要提升周数答案 0 :(得分:1)
在撰写本文时,我对您的问题的编辑仍处于待审状态,您尚未确认我是否正确理解了您的业务规则。假设我有,这是我试图为你准备的解决方案:
from typing import Generator, Dict, List, Tuple
import numpy
TOTAL_WEEKS = 5
def create_default_sales_data_map() -> Dict[int, List[int]]:
"""
Create and return the default mapping of old week sales data
to new averaged week sales data.
The mapping is a tuple specifying the (inclusive) lower and upper
range of weeks to consider the sales data of by default when calculating
the new sales data for the week specified by the dictionary key.
This is based on Table 1.
:return: the default sales data mapping
"""
sales_data_map = {1: (1, 3), 2: (1, 4), 3: (1, 5), 4: (2, 5), 5: (3, 5)}
return sales_data_map
def are_majority_weeks_promoted(promoted_weeks: [bool]) -> bool:
"""
Return if the majority of weeks are promoted or not.
:param promoted_weeks: The promotion status of each week
:return: `true` if the majority of weeks are promoted
"""
return sum(promoted_weeks) >= len(promoted_weeks) / 2
def calculate_new_sales_data(old_sales_data: List[int], promoted_weeks: List[bool]) -> int:
"""
Calculate new (averaged) sales data for a week based on old (raw) sales data and the
promotion status of the relevant weeks.
:param old_sales_data: the old week sales data used by default (i.e. according to Table 1)
:param promoted_weeks: the promotion status of the weeks corresponding to `old_sales_data`
:return: the new sales data for a particular week
"""
majority = are_majority_weeks_promoted(promoted_weeks)
relevant_data = [data for i, data in enumerate(old_sales_data) if promoted_weeks[i] == majority]
new_sales_data = numpy.mean(relevant_data)
return new_sales_data
def calculate_all_new_sales_data(complete_old_sales_data: List[int], complete_promoted_weeks: List[bool]) -> Generator[int, None, None]:
"""
Generates new sales data for all possible weeks based on the supplied sales week data.
:param complete_old_sales_data: the complete set of information on old week sales data
:param complete_promoted_weeks: the promotion status for all weeks
:return: a generator for new sales data
"""
sales_data_map = create_default_sales_data_map()
for week, (lower, upper) in sales_data_map.items():
old_sales_data = complete_old_sales_data[lower-1 : upper]
promoted_weeks = complete_promoted_weeks[lower-1 : upper]
yield calculate_new_sales_data(old_sales_data, promoted_weeks)
def query_user(total_weeks: int) -> Generator[Tuple[int, bool], None, None]:
"""
Query the user for the old sales data values and promoted weeks and return the results.
Each generated tuple contains the old sales data for the week, and whether the week is promoted.
:param total_weeks: the number of weeks' worth of data to query the user for.
:return: a generator of sales data tuples
"""
for i in range(total_weeks):
while True:
try:
old_sales_data = int(input("Total sales data for week {}: $".format(i+1)))
break
except ValueError:
continue
while True:
promotion_status_str = input("Is week promoted (Y/N)? ").lower()
if promotion_status_str in ["y", "n"]:
promotion_status = promotion_status_str == "y"
break
yield old_sales_data, promotion_status
def main():
old_sales_data, promoted_weeks = zip(*query_user(TOTAL_WEEKS))
print()
for week, new_sales_data in enumerate(calculate_all_new_sales_data(old_sales_data, promoted_weeks), 1):
print("Week {} averaged sales data: ${:.2f}".format(week, new_sales_data))
if __name__ == '__main__':
main()
<强>输入强>
Total sales data for week 1: $10
Is week promoted (Y/N)? y
Total sales data for week 2: $20
Is week promoted (Y/N)? y
Total sales data for week 3: $30
Is week promoted (Y/N)? n
Total sales data for week 4: $40
Is week promoted (Y/N)? y
Total sales data for week 5: $50
Is week promoted (Y/N)? n
<强>输出强>
Week 1 averaged sales data: $15.00
Week 2 averaged sales data: $23.33
Week 3 averaged sales data: $23.33
Week 4 averaged sales data: $30.00
Week 5 averaged sales data: $40.00
<强>解释强>
我们可以使用这些值来测试行为是否正确。例如,让我们这样做,以便默认为“新”销售第1周数据考虑的大部分时间不会被提升:
Total sales data for week 1: $10
Is week promoted (Y/N)? y
Total sales data for week 2: $20
Is week promoted (Y/N)? n
Total sales data for week 3: $30
Is week promoted (Y/N)? n
...
Week 1 averaged sales data: $25.00
在这种情况下,只考虑第2周和第3周。
如果提前三周都升级了怎么样?
Total sales data for week 1: $10
Is week promoted (Y/N)? y
Total sales data for week 2: $20
Is week promoted (Y/N)? y
Total sales data for week 3: $30
Is week promoted (Y/N)? y
...
Week 1 averaged sales data: $20.00
在这里,我们考虑所有周,并平均他们的销售数据。
答案 1 :(得分:0)
这会有意义吗?
sales_new[1] = average(sales_old[1],sales_old[2])
sales_new[2] = average(sales_old[1],sales_old[2],sales_old[3])
sales_new[3] = average(sales_old[2],sales_old[3],sales_old[4])
sales_new[4] = average(sales_old[3],sales_old[4],sales_old[5])
sales_new[5] = average(sales_old[4],sales_old[5])
if promo_1 then:
sales_new[1] = sales_old[1]
if promo_2 then:
sales_new[2] = sales_old[2]
if promo_3 then:
sales_new[3] = sales_old[3]
if promo_4 then:
sales_new[3] = sales_old[3]
if promo_5 then:
sales_new[3] = sales_old[3]
计算&#39;运行&#39;平均,然后根据促销修改它。
注意:您的数组可能是基于索引的,因此它将从sales_new [0]开始。