Something like this could work. For each group where quantity is greater than 4, apply a function that does the row splitting and stores into a temp dataframe, then combine everything together to get your desired output:
df = pd.DataFrame({'idx': ['A', 'B', 'C', 'D'],
'quantity': [3, 4, 10, 11]})
def split_quant(df):
quantities = ([4]*(df['quantity'].iat[0] // 4)) + [df['quantity'].iat[0] % 4]
temp = pd.DataFrame({'idx': df['idx'].iat[0],
'quantity': quantities
}, index=range(len(quantities)))
temp = temp[temp['quantity']!=0]
return temp
df_split = df[df['quantity'] > 4].groupby('idx').apply(split_quant)
output = df[df['quantity'] <= 4].append(df_split).reset_index(drop=True)
writer = pd.ExcelWriter('output.xlsx')
output.to_excel(writer, 'Sheet1', index=False)
writer.save()
The above will give you the following output dataframe:
idx quantity
0 A 3
1 B 4
2 C 4
3 C 4
4 C 2
5 D 4
6 D 4
7 D 3
EDIT:
I took the liberty of running some timing tests of the various methods. Using Pandas' groupby and apply saves a lot of time and avoids the nested loops over the input data (although I'm sure theres an even faster way that can avoid the apply as well...)
Mine:
5.49 ms ± 240 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
@Iqbal Basyar:
22.8 ms ± 1.47 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
@sobek
17.7 ms ± 922 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)