I am working on a project where I know store_code, product_code, a bigger product group "pmg" and a percentage per pmg which says how % of products the employees touch but right now I should know how many are these products accurately and put "1" next to them randomly.
My question is there is any quicker solution for calculating which product_code should get "1" than this below? because I have originally more than 480 000 rows and it takes 2h30m to iterate through df ("product_numbers_we_need_per_pmg ") and set "1" next to proper product? thank you for your help in advance
from tqdm import tqdm
import random
import pandas as pd
import numpy as np
def filter(df : pd.DataFrame, perc_to_cases_nr : pd.DataFrame):
def tpn_lottery(tpn_list : list, count : int):
return random.sample(tpn_list, count)
selection = pd.Series(dtype = "int64")
total_dict = product_numbers_we_need_per_pmg.to_dict('records')
for row in tqdm(total_dict):
df_part = df.loc[(df.store_code == row['store_code']) & (df.pmg == row['pmg'])]
unique_tpns = set(df_part['product_code'])
cases_nr = row["how_many_cases_we_need"]
selected_tpn_list = tpn_lottery(unique_tpns, cases_nr)
selection = pd.concat([selection, df_part['product_code'].isin(selected_tpn_list)])
return selection
# creating a df and another df (product_numbers_we_need_per_pmg ) which identifies where to need to put "1" in original df randomly
rand = np.random.randint(2**22, size=(2**16, 27))
a = [f"BWS0{i}"for i in range(1,10)]
b = [f"DRY0{i}"for i in range(1,10)]
c = [f"HEA0{i}"for i in range(1,10)]
df = pd.DataFrame(rand, columns = a+b+c ).melt(var_name = "pmg", value_name = "product_code").drop_duplicates()
df['store_code'] = 87001
product_numbers_we_need_per_pmg = df.copy()
product_numbers_we_need_per_pmg = product_numbers_we_need_per_pmg.groupby(['store_code',"pmg"]).agg(unique_product_no = ("product_code", 'nunique')).reset_index()
product_numbers_we_need_per_pmg['percentage_to_be_indicated'] = 0.15
product_numbers_we_need_per_pmg['how_many_cases_we_need'] = round(product_numbers_we_need_per_pmg['unique_product_no'] * product_numbers_we_need_per_pmg['percentage_to_be_indicated'],0).astype("int64")
df['Pre-sorted Cases'] = 0
df.loc[filter(df, product_numbers_we_need_per_pmg), "Pre-sorted Cases"] = 1