Stacey
Stacey

Reputation: 5097

Key error in data-frame handling in Pandas

I have a dataframe stockData. A part example looks like:

Name: BBG.XCSE.CARLB.S_LAST_ADJ    BBG.XCSE.CARLB.S_FX  .....
date
2015-09-11    0.1340                           490.763
2015-09-14    0.1340                           484.263
2015-09-15    0.1340                           484.755
2015-09-16    0.1340                           507.703
2015-09-17    0.1340                           514.104  .....

each column has a data type , dtype: float64

I am looping a static data dataframe which contans every name in my universe and I iterate through this, then iterating through each day for each name (in this example the name is BBG.XCSE.CARLB.S but there are hundreds of names in reality) taking the column 'name_LAST_ADJ' and multiplying by the column 'name_FX'.

The code that I am using looks like:

for i, row in staticData.iterrows():

        unique_id = i

        #Create new column for the current name that will take the result of the following calculation
        stockData[unique_id+"_LAST_ADJ_EUR"] = np.nan

        #Perform calculation - this is where I get the KeyError when there is no data in the name_ADJ_LAST column.
        stockData[unique_id+"_LAST_ADJ_EUR"] = stockData[unique_id+"_FX"]*stockData[unique_id+"_LAST_ADJ"]


    return stockData

However sometimes the data does not exist (because there is no history for the name) and I receive a key error because the columns for the name are not in the data-frame.

With the above code I am trying to create an additional column called name_LAST_ADJ_EUR and when there is data it should look like:

Name: BBG.XCSE.CARLB.S_LAST_ADJ    BBG.XCSE.CARLB.S_FX     BBG.XCSE.CARLB.S_LAST_ADJ_EUR
    date
    2015-09-11    0.1340                       490.763              65.762242
    2015-09-14    0.1340                       484.263              64.891242
    2015-09-15    0.1340                       484.755              64.95717
    2015-09-16    0.1340                       507.703              68.032202
    2015-09-17    0.1340                       514.104              68.889936

and when there is data no data in the name_LAST_ADJ column is there a way generate an NaN output for the column so it looks like:

Name:      BBG.XCSE.CARLB.S_LAST_ADJ_EUR
    date
    2015-09-11    NaN    
    2015-09-14    NaN       
    2015-09-15    NaN       
    2015-09-16    NaN         
    2015-09-17    NaN        

I have tried using the following:

stockData[unique_id+"_LAST_ADJ_EUR"] = np.where((stockData[unique_id+"_LAST_ADJ"] == np.nan),stockData[unique_id+"_LAST_ADJ_EUR"]='NaN',stockData[unique_id+"_LAST_ADJ_EUR"] = stockData[unique_id+"_FX"] * stockData[unique_id+"_LAST_ADJ"])

which would be fine if there was a column but when there is no column to reference it throws the KeyError exception.

Upvotes: 3

Views: 1280

Answers (2)

piRSquared
piRSquared

Reputation: 294218

I'd start by parsing your columns into a multiindex

tups = df.columns.to_series() \
         .str.extract(r'(.*)_(LAST_ADJ|FX)', expand=False) \
         .apply(tuple, 1).tolist()

df.columns = pd.MultiIndex.from_tuples(tups).swaplevel(0, 1)

df

enter image description here

Then multiplication becomes simple

df.LAST_ADJ * df.FX

enter image description here

Tricky part for me is inserting it back with 'EUR'. I did this

pd.concat([df, pd.concat([df.LAST_ADJ.mul(df.FX)], axis=1, keys=['EUR'])], axis=1)

enter image description here

Upvotes: 1

wflynny
wflynny

Reputation: 18521

In your for loop, try adding something akin to

for uid, row in staticData.iterrows():
    if uid not in stockData.columns:
        stockData[uid + "_FX"] = np.nan
        stockData[uid + "_LAST_ADJ"] = np.nan

    # continue with what you have:
    # no longer needed
    #stockData[uid+"_LAST_ADJ_EUR"] = np.nan

    stockData[uid+"_LAST_ADJ_EUR"] = stockData[uid+"_FX"]*stockData[uid+"_LAST_ADJ"]

While doing it inside the for loop is probably most efficient, you could also do it all at once like:

stockData = pd.concat([stockData, pd.DataFrame(columns=staticData.index)])

For example:

df = pd.DataFrame(np.random.rand(10, 3), columns=list('abc'))
          a         b         c
0  0.627303  0.183463  0.714470
1  0.458124  0.135907  0.515340
2  0.629373  0.725247  0.306275
3  0.113927  0.259965  0.996407
4  0.321131  0.734002  0.766044
5  0.740858  0.238741  0.531810
6  0.063990  0.974056  0.178260
7  0.977651  0.047287  0.435681
8  0.972060  0.606288  0.600896
9  0.250377  0.807237  0.153419

pd.concat([df, pd.DataFrame(columns=list('abcde'))])
          a         b         c    d    e
0  0.627303  0.183463  0.714470  NaN  NaN
1  0.458124  0.135907  0.515340  NaN  NaN
2  0.629373  0.725247  0.306275  NaN  NaN
3  0.113927  0.259965  0.996407  NaN  NaN
4  0.321131  0.734002  0.766044  NaN  NaN
5  0.740858  0.238741  0.531810  NaN  NaN
6  0.063990  0.974056  0.178260  NaN  NaN
7  0.977651  0.047287  0.435681  NaN  NaN
8  0.972060  0.606288  0.600896  NaN  NaN
9  0.250377  0.807237  0.153419  NaN  NaN

Upvotes: 1

Related Questions