Search code examples
pandasdictionaryfor-loopkeyerror

Using a for loop produces a key error


I have a pandas dataframe called alleles that looks like this:

         0    1    2    3    4    5    6    7    8    9 
40011    0    0    0    0    0    0    0    0    0    0
40012    0    0    0    0    0    0    0    0    0    0
40013    0    0    0    0    1    0    0    0    0    0
40014    0    0    0    0    0    0    0    0    0    0   

And I would like to map a value in place of all the 1's.

alleles[0] = alleles[0].map({'1' : 20, '0': 0})

Doing what is shown above successfully replaces all the values for the specified column.

for i in alleles:
    alleles[i] = alleles[i].map({'1' : Merged_transpose[1][0], '0': 0})

But doing a for loop, as shown above, produces:

KeyError: 1

Solution

  • data = {40011 : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],                  
            40012 : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],                  
            40013 : [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],                  
            40014 : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}        
    
    alleles = pd.DataFrame.from_dict(data, orient='index')
    
    In [333]: alleles
    Out[333]: 
           0  1  2  3  4  5  6  7  8  9
    40011  0  0  0  0  0  0  0  0  0  0
    40012  0  0  0  0  0  0  0  0  0  0
    40013  0  0  0  0  1  0  0  0  0  0
    40014  0  0  0  0  0  0  0  0  0  0
    

    You've indicated that your single index mapping works, but...

    alleles[0] = alleles[0].map({'1' : 20, '0': 0})
    
    In [335]: alleles
    Out[335]: 
            0  1  2  3  4  5  6  7  8  9
    40011 NaN  0  0  0  0  0  0  0  0  0
    40012 NaN  0  0  0  0  0  0  0  0  0
    40013 NaN  0  0  0  1  0  0  0  0  0
    40014 NaN  0  0  0  0  0  0  0  0  0
    

    It looks like you're mapping against a str rather than the int contained in the dataframe. If you change the mapping the result seems to be more consistent with your desired output. (reset dataframe)

    alleles[0] = alleles[0].map({1 : 20, 0: 0})  #<-- note: no quotes around 1 or 0
    alleles[4] = alleles[4].map({1 : 20, 0: 0})  #<-- note: no quotes around 1 or 0
    
    In [340]: alleles
    Out[340]: 
           0  1  2  3   4  5  6  7  8  9
    40011  0  0  0  0   0  0  0  0  0  0
    40012  0  0  0  0   0  0  0  0  0  0
    40013  0  0  0  0  20  0  0  0  0  0
    40014  0  0  0  0   0  0  0  0  0  0
    

    Now if we apply that mapping change to your for loop we get (reset dataframe):

    for i in alleles:
        alleles[i] = alleles[i].map({1 : 20, 0: 0})
    
    In [344]: alleles
    Out[344]: 
           0  1  2  3   4  5  6  7  8  9
    40011  0  0  0  0   0  0  0  0  0  0
    40012  0  0  0  0   0  0  0  0  0  0
    40013  0  0  0  0  20  0  0  0  0  0
    40014  0  0  0  0   0  0  0  0  0  0
    

    The only open question then would be if your Merged_transpose[1][0] is the problem - but no way to know without knowing what it is or what it does...

    update

    After some more fiddling - your issue is with the Merged_transpose object and, most likely, the first index your passing. After fixing the mapping dictionary it doesn't through KeyError: 1 regardless.