1

I have two pandas DataFrames with the same DateTime index.

The first one is J:

            A     B     C
01/01/10    100   400   200
01/02/10    300   200   400
01/03/10    200   100   300

The second one is K:

             100    200    300    400
01/01/10     0.05  -0.42   0.61  -0.12
01/02/10    -0.23   0.11   0.82   0.34
01/03/10    -0.55   0.24  -0.01  -0.73

I would like to use J to reference K and create a third DataFrame L that looks like:

             A      B      C
01/01/10     0.05  -0.12  -0.42
01/02/10     0.82   0.11   0.34
01/03/10     0.24  -0.55  -0.01

To do so, I need to take each value in J and look up the corresponding value in K where the column name is that value for the same date.

I tried to do:

L = J.apply( lambda x: K.loc[ x.index, x ], axis='index'  )

but get:

ValueError: If using all scalar values, you must pass an index

I would ideally like to use this so that any NaN values contained in J will remain as is, and will not be looked up in K. I had unsuccessfully tried this:

L = J.apply( lambda x: np.nan if np.isnan( x.astype( float ) ) else K.loc[ x.index, x ]  )
SamC24
  • 13
  • 3

2 Answers2

0

Use DataFrame.melt and DataFrame.stack to use DataFrame.join to map the new values, then We return the DataFrame to original shape with DataFrame.pivot:

#if neccesary
#K = K.rename(columns = int)
L = (J.reset_index()
      .melt('index')
      .join(K.stack().rename('new_values'),on = ['index','value'])
      .pivot(index = 'index',
             columns='variable',
             values = 'new_values')
      .rename_axis(columns = None,index = None)
    )
print(L)

Or with DataFrame.lookup

L = J.reset_index().melt('index')
L['value'] = K.lookup(L['index'],L['value'])
L = L.pivot(*L).rename_axis(columns = None,index = None)
print(L)

Output

             A     B     C
01/01/10  0.05 -0.12 -0.42
01/02/10  0.82  0.11  0.34
01/03/10  0.24 -0.55 -0.01

I think that apply could be a good option but I'm not sure, I recommend you see When should I want use apply in my code

ansev
  • 30,322
  • 5
  • 17
  • 31
0

Use DataFrame.apply with DataFrame.lookup for label based indexing.

# if needed, convert columns of df2 to integers
# K.columns = K.columns.astype(int)
L = J.apply(lambda x: K.lookup(x.index, x))
             A     B     C
01/01/10  0.05 -0.12 -0.42
01/02/10  0.82  0.11  0.34
01/03/10  0.24 -0.55 -0.01
Erfan
  • 40,971
  • 8
  • 66
  • 78