Reputation: 125
I have the following data frame:
A | B | C | D | ListVal
---------------------------------
0 | 3 | 2 | 1 | [0.0,0.1,0.2,0.3]
---------------------------------
2 | 1 | 0 | 3 | [0.5,0.6,0.7,0.8]
---------------------------------
2 | 3 | 1 | 0 | [0.15,0.25,0.35,0.45]
For each row, I would like to use the numbers in columns A-D as indices to the list in column ListVal, and fill the values in the respective columns. So for the above data frame, I want to convert it to:
A | B | C | D | ListVal
-----------------------------------------
0.0 | 0.3 | 0.2 | 0.1 | [0.0,0.1,0.2,0.3]
-----------------------------------------
0.7 | 0.6 | 0.5 | 0.8 | [0.5,0.6,0.7,0.8]
-----------------------------------------
0.35| 0.45| 0.25| 0.15| [0.15,0.25,0.35,0.45]
Note that indices per row are non-repeating.
I tried to do this using numpy by converting last column into a matrix and the first four columns to another matrix. But stuck there, as well!
Upvotes: 3
Views: 348
Reputation: 339710
Since you were asking about a numpy solution:
import pandas as pd
import numpy as np
df=pd.DataFrame({'A':[0,2,2],'B':[3,1,3],'C':[2,0,1],'D':[1,3,0],
'listVal':[[0.0,0.1,0.2,0.3],[0.5,0.6,0.7,0.8],[0.15,0.25,0.35,0.45]]})
a = df[range(4)].values
b = np.array(list(df["listVal"].values))
c = b[:,a].diagonal(0,0,1).T
newdf = pd.DataFrame(c, columns=df.columns[:-1])
newdf["listVal"] = df["listVal"]
print newdf
Mind that this creates a large overhead, since the indexing b[:,a]
adds another dimension.
Upvotes: 1
Reputation: 3382
Here is how I would do it in 2 lines of code:
the dataframe:
df1=pd.DataFrame({'A':[0,2,2],'B':[3,1,3],'C':[2,0,1],'D':[1,3,0],'ListVal':[[0.0,0.1,0.2,0.3],[0.5,0.6,0.7,0.8],[0.15,0.25,0.35,0.45]]})
convert it to a list of lists:
df_vals=df1.values.tolist()
and use the following list comprehension:
desired=[[d[4][e] if i<4 else e for i,e in enumerate(d)]for d in df_vals]
and convert back to a Dataframe if you want:
df=pd.DataFrame(desired, columns=['A','B','C','D','ListVal'])
output:
print df
A B C D ListVal
0 0.00 0.30 0.20 0.10 [0.0, 0.1, 0.2, 0.3]
1 0.70 0.60 0.50 0.80 [0.5, 0.6, 0.7, 0.8]
2 0.35 0.45 0.25 0.15 [0.15, 0.25, 0.35, 0.45]
Upvotes: 2