[FRPythoneers] Weighted List

Sue Giller climber at hydrosphere.com
Tue May 6 14:42:38 MDT 2003


We have developed an in-house set of distributions, and one of 
them is a discrete weighted one that sounds similar to what you 
want.  It is assumed that the weightings must sum to 1 when 
definining the distribution.

HTH

Code follows:

import whrandom,random,math

class distribution:
   """ base class for all distributions """
   def __call__(self):
      # used when class called as function
      return self.sample()

   def __getitem__(self, i):
      # return ith item - which is generated by the sample() function
      return self.sample()

class discrete(distribution):
   """ returns set values based on their weights """
   # inputs are a tuple of 1 or more sets of wt:value pairs
   def __init__(self, pairList):
      pairs = pairList[:]
      sum = 0.0
      self._values = []
      self._weights = []
      for pair in pairs:
         wt, value = pair
         if wt < 0 or wt > 1.0:
            raise AttributeError, "weight outside 0 and 1 range: %s" % 
`pair`
         sum += wt
         self._weights.append(sum)
         self._values.append(value)
      if abs(sum - 1.0) > .001:
         raise AttributeError, "weights don't sum to 1.0: %.3f" % sum

   def sample(self):
      # generate random value between 0 and 1 and see what value to 
return
      weight = whrandom.random()
      for ii in range(len(self._weights)):
         bin = self._weights[ii]
         if weight > bin:
            continue
         return self._values[ii]
      # what happens if we get here?

'for testing.  If you run a histogram on the output for the following, it 
shows the distribution to match the weightings.
print 'test discrete'
wts = [(.0375, .0089), (.025, .009), (.05, .0092),
          (.15, .0097), (.25, .0105,), (.25, .012),
          (.15, .0141), (.05, .0164), (.0375, .0181)
        ]
 dist = discrete(wts)
 for i in range(100):
      print dist()



More information about the FRPythoneers mailing list