1
$\begingroup$

I would like to build a pandas random dataframe. To fulfill that purpose I need a Python function taking as arguments :

  • numpy distributions
  • their arguments.

For example :

distribution 1 : normal | arguments : means = 0 , standard dev = 1 , size = 100

distribution 2 : uniform | arguments : low = 0 , high = 1 , size = 100

etc...

I do not know in advance what will be the different distributions and their arguments.

The main function will then generate random samples of the distributions using each corresponding arguments.

I have tried something like :

import numpy as np

def myfun( **kwargs ) :
    for k , v in kwargs.items() :
        print( k )
        print( v )

When I call that function with these arguments :

myfun( fun_1 = 'np.random.normal' , arg_1 = { 'loc' : 0 , 'scale' : 1 , 'size' : 7 } ,
       fun_2 = 'np.random.uniform' , arg_2 = { 'low' : 0 , 'high' : 1 , 'size' : 7 } )

The output is :

fun_1
np.random.normal
arg_1
{'loc': 0, 'scale': 1, 'size': 7}
fun_2
np.random.uniform
arg_2
{'low': 0, 'high': 1, 'size': 7}

But my purpose is not to print the desired distributions and their associated parameters but to generate a sample for each distributions.

$\endgroup$
3
  • $\begingroup$ The requested function can be created with core Python functions/operators. If reopened I will post an answer. $\endgroup$
    – Edmund
    Commented Jun 13, 2019 at 0:47
  • $\begingroup$ My question [ on hold ] and its seems it will stay in that state despite the many changes I have made on it. I am trying using kwargs but i have not been successful so far. $\endgroup$ Commented Jun 14, 2019 at 10:46
  • $\begingroup$ It takes a little time for the function to reopen as it needs more than one reopen vote. Give it a little time. $\endgroup$
    – Edmund
    Commented Jun 14, 2019 at 11:18

1 Answer 1

1
$\begingroup$

I assume you know which distributions are possible once you are inside your function? I would probably just pass a parameter for the distribution name and then a set of parameters in a Python dictionary.

This method also allows for pretty easy testing, because you know that distributions expects only certain parameters, so you can also add small checks to confirm everything is available.

def my_distribution(dist_name, dist_params):
    if dist_name == "normal":
        assert ("mean" in params.keys()) and ("variance" in params.keys()), "Missing expected parameters for {} distribution".format(dist_name)
    # Perform some checks for other distributions as necessary...

    # perform your own steps...

Now you use it like this:

# assume these are provided by your earlier code
distr = "normal"
params = {"mean": 5.0, "variance": 2.0}

result = my_distribution(dist_name=distr, dist_params=params)

Edit:

Here is an example of a single function that can handle multiple distributions in a single call:

def my_distributions(dist_collection):
    # Perform some checks for other distributions as necessary...
    allowed_dists = ["normal", "uniform", "dirichlet", "rayleigh"]
    assert all(
        dist_name in allowed_dists for dist_name in dist_collection
    ), "Input contains disallowed distribution"

    # Do something for each distribution name with its parameters:
    for dist_name, dist_params in params.items():
        print(dist_name, dist_params)

Now the input needs to be specified a little differently:

all_distributions = {
    "normal": {"loc": 1, "scale": 2, "size": 100},
    "uniform": {"low": 0, "high": 1, "size": 100},
}

A single call can now work over many distributions:

my_distributions(all_distributions)

You could of course make classes that hold all configurations and checks, but I would argue you are starting to make things unnecessarily complicated, as Numpy does so much for you already with it's built-in distribution capabilities.

$\endgroup$
4
  • $\begingroup$ Ok, thanks. With my_distribution function it seems that I can only manage one distribution at a time. My purpose is to deal with multiple distributions and their own parameters in one call of the function. $\endgroup$ Commented Jun 11, 2019 at 17:56
  • $\begingroup$ That should be an easy extension of my example... You can simply pass a list of distributions and then a dictionary that contains each distribution as a key with its parameters as another dictionary, as in my example. Or just one dictionary with the key as the distribution and the value as a dictionary of parameters for that distribution. $\endgroup$
    – n1k31t4
    Commented Jun 11, 2019 at 18:00
  • $\begingroup$ @FabriceBOUCHAREL - please see my edit that includes a new function for multiple distributions. $\endgroup$
    – n1k31t4
    Commented Jun 11, 2019 at 19:59
  • $\begingroup$ I have a problem with the "Do something for each distribution name with its parameters" section : what I want to do is to call the distribution functions with their arguments but I don't know how to proceed. Something like dist_name(dist_params) does not work. $\endgroup$ Commented Jun 12, 2019 at 5:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.