Function of functions and theirs arguments 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.
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.