user14385273
user14385273

Reputation:

How to create new rows in pandas by dictionary

I have a problem with pandas DataFrame - I don't understand how I can create new rows and merge them with a dictionary.

For instanse, I have this dataframe:

shops = [{'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'Rexona', 'Value': 10},
    {'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'AXE', 'Value': 20},
    {'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'Old Spice', 'Value': 30},
    {'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'Camel', 'Value': 40},
    {'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'Dove', 'Value': 50},   
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'Rexona', 'Value': 10},
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'CIF', 'Value': 20},
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'Old Spice', 'Value': 30},
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'Camel', 'Value': 40}]

Initial DataFrame

At the same time, I have a dictionary dataframe with Chain-Brand connection:

chain_brands = [{'Chain': 'SeQu', 'Brand': 'Rexona'},
    {'Chain': 'SeQu', 'Brand': 'Axe'},
    {'Chain': 'SeQu', 'Brand': 'Old Spice'},
    {'Chain': 'SeQu', 'Brand': 'Camel'},
    {'Chain': 'SeQu', 'Brand': 'Dove'},
    {'Chain': 'SeQu', 'Brand': 'CIF'}]

Distionary

So, I need to create new rows and fill them with 0, if brand in Null. It should look like this:

output = [{'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'Rexona', 'Value': 10},
    {'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'AXE', 'Value': 20},
    {'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'Old Spice', 'Value': 30},
    {'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'Camel', 'Value': 40},
    {'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'Dove', 'Value': 50},
    {'Chain': 'SeQu', 'Shop': 'Rimme', 'Location': 'UK', 'Brand': 'CIF', 'Value': 0},
     
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'Rexona', 'Value': 10},
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'CIF', 'Value': 20},
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'Old Spice', 'Value': 30},
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'Axe', 'Value': 0},
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'Camel', 'Value': 40},
    {'Chain': 'SeQu', 'Shop': 'Rum', 'Location': 'USA', 'Brand': 'Dove', 'Value': 0}]

Result

Thanks!

Upvotes: 1

Views: 58

Answers (1)

Shaido
Shaido

Reputation: 28422

You can create a multi-index from the chain_brands dataframe and then use groupby together with reindex to solve this:

mi = pd.MultiIndex.from_arrays(chain_brands.values.T, names=['Chain', 'Brand'])

s = shops.set_index(['Chain', 'Brand']).\
    groupby(['Location', 'Shop']).\
    apply(lambda x: x.reindex(mi, fill_value=0)).\
    drop(columns=['Location', 'Shop']).\
    reset_index()

Result:

   Location   Shop Chain      Brand  Value
0        UK  Rimme  SeQu     Rexona     10
1        UK  Rimme  SeQu        Axe      0
2        UK  Rimme  SeQu  Old Spice     30
3        UK  Rimme  SeQu      Camel     40
4        UK  Rimme  SeQu       Dove     50
5        UK  Rimme  SeQu        CIF      0
6       USA    Rum  SeQu     Rexona     10
7       USA    Rum  SeQu        Axe      0
8       USA    Rum  SeQu  Old Spice     30
9       USA    Rum  SeQu      Camel     40
10      USA    Rum  SeQu       Dove      0
11      USA    Rum  SeQu        CIF     20

Upvotes: 0

Related Questions