2

I am wanting to learn how to convert a dictionary into a square matrix. From what I have read, I may need to convert this into a numpy array and then reshape it. I do not want to use reshape as I want to be able to do this based on information a user puts in. In other words, I want a code to give out a square matrix no matter how many owners and breeds are input by the user.

Note: The owners and breeds for this dictionary vary upon user input. A user can input 100 names and 50 breeds, or they can input 4 names and 5 breeds. In this example, I did four names and three dogs.

dict1 = 
{'Bob VS Sarah': {'shepherd': 1,'collie': 5,'poodle': 8},
'Bob VS Ann': {'shepherd': 3,'collie': 2,'poodle': 1},
'Bob VS Jen': {'shepherd': 3,'collie': 2,'poodle': 2},
'Sarah VS Bob': {'shepherd': 3,'collie': 2,'poodle': 4},
'Sarah VS Ann': {'shepherd': 4,'collie': 6,'poodle': 3},
'Sarah VS Jen': {'shepherd': 1,'collie': 5,'poodle': 8},
'Jen VS Bob': {'shepherd': 4,'collie': 8,'poodle': 1},
'Jen VS Sarah': {'shepherd': 7,'collie': 9,'poodle': 2},
'Jen VS Ann': {'shepherd': 3,'collie': 7,'poodle': 2},
'Ann VS Bob': {'shepherd': 6,'collie': 2,'poodle': 5},
'Ann VS Sarah': {'shepherd': 0,'collie': 2,'poodle': 4},
'Ann VS Jen': {'shepherd': 2,'collie': 8,'poodle': 2},
'Bob VS Bob': {'shepherd': 3,'collie': 2,'poodle': 2},
'Sarah VS Sarah': {'shepherd': 3,'collie': 2,'poodle': 2},
'Ann VS Ann': {'shepherd': 13,'collie': 2,'poodle': 4},
'Jen VS Jen': {'shepherd': 9,'collie': 7,'poodle': 2}}

For example, I want a 4 x 4 matrix (again, the user can input any number of dog breeds so 3 breeds is not a restriction), since there are four owners.

I apologize ahead of time for not putting in what I want the end result to look like and usually I do. I am just proud of myself for making dict1 :). So the dictionary should be in a form similar to below, but I am not sure how to incorporate the different breeds. The hard part for me is that I am only needing one matrix. I also plan on using the matrix solver numpy has, hence why I am wanting to figure out how to get a square matrix from a dictionary.

      Bob      Sarah     Ann     Jen
Bob

Sarah

Ann

Jen
Caroline.py
  • 293
  • 1
  • 4
  • 16
  • Could you clarify what you want the end result to be? Is it something like the row 'Ann' and col 'Ann' in the matrix should have the value `{'shepherd': 13,'collie': 2,'poodle': 4}`? – gowrath Aug 24 '16 at 01:44
  • Yes, (Ann,Ann) will be {'shepherd': 13,'collie': 2,'poodle': 4}. I am not sure whether to convert this directly to an array first and then back to a dictionary. – Caroline.py Aug 24 '16 at 01:49

2 Answers2

4

If you can get your data in the format

{name1: {name1:data, name2:data, name3:data, ...}, 
 name2: {name1:data, name2:data, name3:data, ...},
 ...
}

then you can just hand it to a pandas DataFrame and it will make it for you. The data at position row = name1 and col = name2 will be the value of name1 vs name2. Here is the code that will do it:

from collections import defaultdict
import pandas

result = defaultdict(dict)
for key,value in dict1.items():
     names = key.split()
     name1 = names[0]
     name2 = names[2]    
     result[name1][name2] = value

df = pandas.DataFrame(result).transpose()
print(df)

This gives the following output:

                              Ann                                  Bob                                        Jen                                      Sarah
Ann    {'shepherd': 13, 'collie': 2, 'poodle': 4}  {'shepherd': 6, 'collie': 2, 'poodle': 5}  {'shepherd': 2, 'collie': 8, 'poodle': 2}  {'shepherd': 0, 'collie': 2, 'poodle': 4}
Bob     {'shepherd': 3, 'collie': 2, 'poodle': 1}  {'shepherd': 3, 'collie': 2, 'poodle': 2}  {'shepherd': 3, 'collie': 2, 'poodle': 2}  {'shepherd': 1, 'collie': 5, 'poodle': 8}
Jen     {'shepherd': 3, 'collie': 7, 'poodle': 2}  {'shepherd': 4, 'collie': 8, 'poodle': 1}  {'shepherd': 9, 'collie': 7, 'poodle': 2}  {'shepherd': 7, 'collie': 9, 'poodle': 2}
Sarah   {'shepherd': 4, 'collie': 6, 'poodle': 3}  {'shepherd': 3, 'collie': 2, 'poodle': 4}  {'shepherd': 1, 'collie': 5, 'poodle': 8}  {'shepherd': 3, 'collie': 2, 'poodle': 2}

A simple conversion to a numpy array would look like:

numpy_array = df.as_matrix()
print(numpy_array)

[[{'shepherd': 13, 'collie': 2, 'poodle': 4}
  {'shepherd': 6, 'collie': 2, 'poodle': 5}
  {'shepherd': 2, 'collie': 8, 'poodle': 2}
  {'shepherd': 0, 'collie': 2, 'poodle': 4}]
 [{'shepherd': 3, 'collie': 2, 'poodle': 1}
  {'shepherd': 3, 'collie': 2, 'poodle': 2}
  {'shepherd': 3, 'collie': 2, 'poodle': 2}
  {'shepherd': 1, 'collie': 5, 'poodle': 8}]
 [{'shepherd': 3, 'collie': 7, 'poodle': 2}
  {'shepherd': 4, 'collie': 8, 'poodle': 1}
  {'shepherd': 9, 'collie': 7, 'poodle': 2}
  {'shepherd': 7, 'collie': 9, 'poodle': 2}]
 [{'shepherd': 4, 'collie': 6, 'poodle': 3}
  {'shepherd': 3, 'collie': 2, 'poodle': 4}
  {'shepherd': 1, 'collie': 5, 'poodle': 8}
  {'shepherd': 3, 'collie': 2, 'poodle': 2}]]
gowrath
  • 3,136
  • 2
  • 17
  • 32
  • I've heard great things about pandas. I am a beginner at Python, I am not sure if I am ready to go on a tangent just yet – Caroline.py Aug 24 '16 at 02:16
  • 1
    @Caroline.py The issue is that, although numpy arrays are excellent with matrix work, they are not very friendly with having names for the row and column values. This is the space that pandas fills in. The good thing is, it is unbelievable easy to convert a pandas array into a numpty array. All you have to do is `numpy_array = df.as_matrix()` and then you can do any analysis you want to using numpy. Essential: pandas is for the human eye, numpy is for the computer. – gowrath Aug 24 '16 at 02:18
0

You may achieve this via generating a nested dictionary like:

{'Bob':   {'Bob': .., 'Sarah': .., 'Ann': .., 'Jen':..}
 'Sarah': {.. .. ..},
 'Ann':   {.. .. ..},
 'Jen':   {.. .. ..},
 }

Below is the sample code:

>>> my_dict = {'Bob VS Sarah': {'shepherd': 1,'collie': 5,'poodle': 8},
... 'Bob VS Ann': {'shepherd': 3,'collie': 2,'poodle': 1},
... 'Bob VS Jen': {'shepherd': 3,'collie': 2,'poodle': 2},
... 'Sarah VS Bob': {'shepherd': 3,'collie': 2,'poodle': 4},
... 'Sarah VS Ann': {'shepherd': 4,'collie': 6,'poodle': 3},
... 'Sarah VS Jen': {'shepherd': 1,'collie': 5,'poodle': 8},
... 'Jen VS Bob': {'shepherd': 4,'collie': 8,'poodle': 1},
... 'Jen VS Sarah': {'shepherd': 7,'collie': 9,'poodle': 2},
... 'Jen VS Ann': {'shepherd': 3,'collie': 7,'poodle': 2},
... 'Ann VS Bob': {'shepherd': 6,'collie': 2,'poodle': 5},
... 'Ann VS Sarah': {'shepherd': 0,'collie': 2,'poodle': 4},
... 'Ann VS Jen': {'shepherd': 2,'collie': 8,'poodle': 2},
... 'Bob VS Bob': {'shepherd': 3,'collie': 2,'poodle': 2},
... 'Sarah VS Sarah': {'shepherd': 3,'collie': 2,'poodle': 2},
... 'Ann VS Ann': {'shepherd': 13,'collie': 2,'poodle': 4},
... 'Jen VS Jen': {'shepherd': 9,'collie': 7,'poodle': 2}}
>>> new_dict = {}
>>> for key, value in my_dict.iteritems():
...     first_name, second_name = map(lambda x: x.strip(), key.split('VS'))
...     if first_name not in new_dict:
...         new_dict[first_name] = {}
...     new_dict[first_name][second_name] = value
... 
>>> new_dict
{'Sarah': {'Sarah': {'shepherd': 3, 'collie': 2, 'poodle': 2}, 
            'Ann': {'shepherd': 4, 'collie': 6, 'poodle': 3}, 
            'Jen': {'shepherd': 1, 'collie': 5, 'poodle': 8}, 
            'Bob': {'shepherd': 3, 'collie': 2, 'poodle': 4}
          }, 
 'Bob':   {'Sarah': {'shepherd': 1, 'collie': 5, 'poodle': 8}, 
           'Bob': {'shepherd': 3, 'collie': 2, 'poodle': 2}, 
           'Jen': {'shepherd': 3, 'collie': 2, 'poodle': 2}, 
           'Ann': {'shepherd': 3, 'collie': 2, 'poodle': 1}}, 
 'Jen':   {'Sarah': {'shepherd': 7, 'collie': 9, 'poodle': 2}, 
           'Bob': {'shepherd': 4, 'collie': 8, 'poodle': 1}, 
           'Jen': {'shepherd': 9, 'collie': 7, 'poodle': 2}, 
           'Ann': {'shepherd': 3, 'collie': 7, 'poodle': 2}
          }, 
 'Ann': {'Sarah': {'shepherd': 0, 'collie': 2, 'poodle': 4}, 
                   'Bob': {'shepherd': 6, 'collie': 2, 'poodle': 5}, 
                   'Jen': {'shepherd': 2, 'collie': 8, 'poodle': 2},                   
                   'Ann': {'shepherd': 13, 'collie': 2, 'poodle': 4}
        }
}
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • 1
    Avoid just writing code without explanation. This isn't a forum for people to just be provided with code to solve their problem. – gowrath Aug 24 '16 at 02:15
  • Also you can potentially use a defaultdict and avoid the `if first_name not in new_dict` check completely. – gowrath Aug 24 '16 at 02:16