1

How can I make this a dynamic or first class function that essentially passes the criteria to a np.where() call?

def num_assets(obj, criteria=None):
    """
    A flexible wrapper to return the number of assets in a portfolio.

    # list (asset names or characteristics)
    >>> num_assets([1, 2, 3, 4, 5])
    5

    # number (pre-specification)
    >>> num_assets(7)
    7

    # column vector (weights)
    >>> num_assets(np.zeros(shape=(3,1)))
    3

    # matrix (covariance matrix)    
    >>> num_assets(np.eye(10))    
    10

    # criteria.
    >>> num_assets([1, 2, 3, 4, 5], '> 3')
    ??? I AM STUCK HERE AND NEED SOME HELP! Should return 2
    """
    if criteria is None:
        if myc.is_iterable(obj):
            shape_obj = np.shape(obj)
            return max(shape_obj)
        elif myc.is_number(obj):
            return myc.is_number(obj, True)
    else:
        return np.where(criteria)

myc.is_iterable() is essentially a boolean function containing a try except clause to iter notifying me if obj is iterable. myc.is_number() is telling me whether the obj is a number and when I pass the True parameter, it parses the number (in case obj is a string). I consider myself a newbie and know that this should not be too difficult a problem to solve, its just that I am not sure what advanced area of Python I need to apply to solve the criteria type problem (first class objects, meta programming, ...)? Also, if there is a cleaner more pythonic way of formulating the problem/getting the answer, contributions would be most welcome.

Thanks.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Bertie
  • 1,163
  • 3
  • 14
  • 26
  • 1
    The criteria for `np.where` is just an array of booleans (or a list or other-array like that can be converted to an array). – BrenBarn Mar 02 '14 at 19:18
  • http://stackoverflow.com/q/5642457/1903116? – thefourtheye Mar 02 '14 at 19:22
  • The article you mention simply shows the internals of np.where(). Obviously my problem is in getting the top parameters (obj, criteria) to np.where() so that it can do it's thing. Do you think it's possible to solve this problem? Thanks – Bertie Mar 02 '14 at 19:32

1 Answers1

2

If I understand what you mean correctly, then I think this will do what you want.

if criteria is None:
    what you already have
else:
    obj = np.asarray(obj)
    return np.sum(eval('obj'+criteria))

Its not elegant to have to use eval, but I think that's the easiest way to do this. For your example of criteria='>3', this becomes np.sum(obj>3), which is np.sum([False,False,False,True,True]), which is 2. where is not needed here.

amaurea
  • 4,950
  • 26
  • 35