1

Take the following sample dataframe:

df = pd.DataFrame([['00100', 'Alpha', None],
                   ['00100', 'Beta', None],
                   ['05300', 'Theta', None],
                   ['95687', 'Gamma', None],
                   ['05300', 'Sigma', None]])

Which looks like

       0      1     2
0  00100  Alpha  None
1  00100   Beta  None
2  05300  Theta  None
3  95687  Gamma  None
4  05300  Sigma  None

I have a dictionary which maps the values for column 2 depending on the column 0:

match = {
    '00100' : '09010',
    '05300' : '09004'
}

I want to change the values in column 2 depending in the value from column 0. The end result I expect after matching the dict to the dataframe would be:

       0      1      2
0  00100  Alpha  09010
1  00100   Beta  09010
2  05300  Theta   None
3  95687  Gamma  09004
4  05300  Sigma  09004

At first I thought that I could make an .apply function or a for loop using .loc in the following fashion:

df.loc[df[0] == match[key]][2] = match[value]

But this raises an exception:

"A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead"

Which I can't seem to understand how to apply for this particular case.

I am using: Python 3.6.1 Pandas 0.20.1

2 Answers2

4

Try this. pd.Series.map takes a function, dict, or Series.

df[2] = df[0].map(match).fillna(df[2])

#        0      1      2
# 0  00100  Alpha  09010
# 1  00100   Beta  09010
# 2  05300  Theta  09004
# 3  95687  Gamma   None
# 4  05300  Sigma  09004
jpp
  • 159,742
  • 34
  • 281
  • 339
0

Here's one possible solution:

df[2] = df[0].apply(lambda x: match[x] if x in match else None)
sjw
  • 6,213
  • 2
  • 24
  • 39