How can I iterate through a DataFrame in the quickest way in terms of below example?

Viewed 52

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
0 Answers
Related