Q:

Adding unused column combinations to DataFrame

I have the following dataset:
print(df)

  Date      Product_Code     Quantity_ordered
01/01/18         01                 6
02/01/18         04                 3
03/01/18         01                 4
...

I would like to create an additional column "Order",using Pandas that, for each product and day, is equal to 1 if there is a quantity ordered, else 0; for instance:
print(final_df)

  Date      Product_Code          Order
01/01/18         01                 1
01/01/18         04                 0

02/01/18         04                 1
02/01/18         01                 0    

03/01/18         01                 1
03/01/18         04                 0
...

I tried:
a = pd.date_range(min(df["Date"]), max(df["Date"]))
final_df = pd.merge(df, a, on = ["Date", "Product_Code"])

But it reports an error saying that it cannot deal with datetime; furthermore, I don't think it's the most efficient way and I don't know how to create the final binary variable.
Regards

A:

You can use reindex by unique values of Date and Product_Code, what create NaNs for missing rows, so possible check by notnull and cast to 0,1:
mux = pd.MultiIndex.from_product([df['Date'].unique(), df['Product_Code'].unique()], 
                                 names=('Date','Product_Code'))

df1 = (df.set_index(['Date','Product_Code'])['Quantity_ordered']
        .reindex(mux)
        .notnull()
        .astype(int)
        .reset_index()
        .rename(columns={'Quantity_ordered':'Order'}))

Alternative solution is use unstack for reshape - NaNs are added, then check it and cast to 0,1, last for convert back use stack:
df1 = (df.set_index(['Date','Product_Code'])['Quantity_ordered']
         .unstack()
         .notnull()
         .astype(int)
         .stack()
         .reset_index(name='Order')
)

print (df1)
       Date Product_Code  Order
0  01/01/18           01      1
1  01/01/18           04      0
2  02/01/18           01      0
3  02/01/18           04      1
4  03/01/18           01      1
5  03/01/18           04      0

Solution working with duplicates:
print (df)
       Date Product_Code  Quantity_ordered
0  01/01/18           01                 6
1  01/01/18           01                 7
2  02/01/18           04                 3
3  03/01/18           01                 4

from  itertools import product
df1 = pd.DataFrame(list(product(df['Date'].unique(), df['Product_Code'].unique())),
                                columns=('Date','Product_Code'))

print (df1)
       Date Product_Code
0  01/01/18           01
1  01/01/18           04
2  02/01/18           01
3  02/01/18           04
4  03/01/18           01
5  03/01/18           04

df2 = pd.merge(df, df1, how='right').sort_values(['Date','Product_Code'])
df2 = (df2.rename(columns={'Quantity_ordered':'Order'})
         .assign(Order=lambda x:x['Order'].notnull().astype(int)))
print (df2)
       Date Product_Code  Order
0  01/01/18           01      1
1  01/01/18           01      1
4  01/01/18           04      0
5  02/01/18           01      0
2  02/01/18           04      1
3  03/01/18           01      1
6  03/01/18           04      0

