Question: I have a panda data frame with several column of integers, as well as a corresponding dictionary of {column : {integer:string\_label}}.

I am trying to create a dataframe in which the integers have been replaced by their labels. The closest I got is below, but the output is somewhat unexpected.

**Code**

```
import pandas as pd
import numpy as np

df = pd.DataFrame({'a':[1,2,3,3,8],'b':[8,8,8,8,7]})

dic = {'a':{1:"label1",2:"label2",3:"label3"}, 'b':{8:'label8',7:'label7'}}

converters = {column: lambda x: dic[column][x] if x in dic[column].keys() else np.nan for column in dic.keys()}

new = pd.DataFrame.from_dict({col: series.apply(converters[col]) 
                            if col in converters else series
                            for col, series in df.iteritems()})
print new

#Output:
#         a       b
# 0     NaN  label8
# 1     NaN  label8
# 2     NaN  label8
# 3     NaN  label8
# 4  label8  label7

```

Answer: 
As Greg mentioned, the issue is your strings do not match your `levels`. They need to match exactly. To apply this, you could do the following:

```
#starting with user specific data and levels
chr_string <- c("NEW.ENGLAND", "NEW.ENGLAND", "NEW.ENGLAND", "NEW.ENGLAND", "NEW.ENGLAND", "NEW.ENGLAND",
                "NEW.ENGLAND", "NEW.ENGLAND", "MIDDLE.ATLANTIC", "MIDDLE.ATLANTIC", "MIDDLE.ATLANTIC", "MIDDLE.ATLANTIC",
                "MIDDLE.ATLANTIC", "MIDDLE.ATLANTIC", "MIDDLE.ATLANTIC", "E..NOR..CENTRAL", "E..NOR..CENTRAL", "E..NOR..CENTRAL",
                "E..NOR..CENTRAL", "E..NOR..CENTRAL", "E..NOR..CENTRAL", "W..NOR..CENTRAL", "W..NOR..CENTRAL", "W..NOR..CENTRAL",
                "W..NOR..CENTRAL", "W..NOR..CENTRAL", "SOUTH.ATLANTIC",  "SOUTH.ATLANTIC",  "SOUTH.ATLANTIC", "SOUTH.ATLANTIC", 
                "E..SOU..CENTRAL", "E..SOU..CENTRAL", "E..SOU..CENTRAL", "W..SOU..CENTRAL", "W..SOU..CENTRAL", "MOUNTAIN")
levels <- c("NEW ENGLAND", "MIDDLE ATLANTIC", "E. NOR. CENTRAL", "W. NOR. CENTRAL", "SOUTH ATLANTIC", "E. SOU. CENTRAL",
            "W. SOU. CENTRAL", "MOUNTAIN", "PACIFIC") 

#regex to remove periods from your vector of strings
chr_string <- sapply(chr_string, gsub, pattern = '[//.]', replacement = ' ')

#remove double spaces and replace with '. ' string as required by levels
chr_string <- sapply(chr_string, gsub, pattern = '  ', replacement = '. ')

#removing names from the vector
names(chr_string) <- NULL

#as requested; expected result
factor(chr_string, levels = levels)

```

Alternately, just change your `levels`.
The specified levels need to match the character strings. Your first element is "NEW.ENGLAND", but in the levels you have "NEW ENGLAND" (with a space instead of a dot), so R is not going to match them up. When creating the factor those need to match exactly, you can use the `labels` argument to change the level codes after the matching, or you can use a second step and call to `levels` to change the labels.