1
votes

I have a complex data structure that I'm trying to process.

Explanation of the data structure: I have a dictionary of classes. The key is a name. The value is a class reference. The class contains two lists of dictionaries.

Here's a simple example of my data structure:

import scipy.stats

class employee_salaries(object):
    def __init__(self,management, players, disparity):
        self.management = management
        self.players = players
        self.disparity = disparity

# the coach's salary was 12 his 1st year and 11 his 2nd year
mgmt1 = [{'Coach':12, 'Owner':15, 'Team Manager': 13}, {'Coach':11, 'Owner':14, 'Team Manager':15}]
plyrs1 = [{'Point Guard': 14, 'Power Forward':16,},{'Point Guard':16, 'Power Forward':18}]

NBA = {}

mgmt2 = [{'Coach':10, 'Owner':12}, {'Coach':13,'Owner':15}]
plyrs2 = [{'Point Guard':17, 'Power Forward':14}, {'Point Guard': 22, 'Power Forward':16}]

NBA['cavs'] = employee_salaries(mgmt1,plyrs1,0)
NBA['celtics'] = employee_salaries(mgmt2,plyrs2,0)

Let's say I wanted to determine the disparity between the Point Guard's salary and the Owner's salary over these two years.

for key, value in NBA.iteritems():
    x1=[]; x2=[]
    num = len(NBA[key].players)
    for i in range(0,num):
        x1.append(NBA[key].players[i]['Point Guard'])
        x2.append(NBA[key].management[i]['Owner'])
    tau, p_value = scipy.stats.kendalltau(x1, x2)

    NBA[key].disparity = tau
print NBA['cavs'].disparity

Keep in mind this is not my real data. In my actual data structure, there are over 150 keys. And there are more elements in the list of dictionaries. When I run the code above on my real data, I get a runtime error.

RuntimeError: maximum recursion depth exceeded in cmp error.

How can I change the code above so that it doesn't give me a maximum recursion depth error? I want to do this type of comparison and be able to save the value.

1
Example data that does reproduce the error would be useful. Without it, one can only guess where exactly the error occurs; I'd suspect the mergesort in scipy.stats.kendalltau though. Did you try to replace kendalltau with a different implementation? - Phillip
Showing the stack in the error message (or rather, the critical parts of it and describing the rest since it should be extremely large) may help. With this error, there must be excessive recursion. - ivan_pozdeev
Try scipy.stats.kendalltau(x1, x2, initial_lexsort=False). - leewz
The stack in the error message shows File "/usr/lib/python2.7/dist-packages/scipy/stats/stats.py", line 2961, in mergesort exchcnt += mergesort(offs, length0) repeating. - cooldood3490
Try inserting assert len(x1) and len(x2) right before the call to kendalltau. - leewz

1 Answers

3
votes

It's a bug.

Fixed in 0.15.0

You're passing in empty arrays, and the function handles it incorrectly. Either update your Scipy, or skip if the arrays are empty (though check that your data isn't wrong and that it makes sense to have an empty array there).


Some suggestions for your code.

for team in NBA.itervalues():
#Or `for name, team in NBA.iteritems()` if you use the name.
    x1, x2 = [], []
    # Not `x1 = x2 = []`, since that would be two names for one list

    for player, manager in izip(team.players, team.management):
        x1.append(player['Point Guard'])
        x2.append(manager['Owner'])
    # Or lose the `for` loop and say:
    # `x1 = [player['Point Guard'] for player in team.players]`
    # `x2 = [manager['Owner'] for manager in team.management]`
    # (This can be more efficient.)

    tau, p_value = scipy.stats.kendalltau(x1, x2)

    team.disparity = tau

print NBA['cavs'].disparity