2

I'm trying to generate an numpy array with randomly generated elements (it's similar like bernouilli distribution. The thing is I want to achieve it without using numpy.random.binomial function). Only function that fits after searching documentation and some forums is numpy.fromfunction. But I encountered a problem that this function doesn't generate n elements, but one.

I expect output something like:

[0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1]

This function generates 1 element only, no matter what shape is in tuple:

np.fromfunction(lambda i : np.random.choice([0, 1], p=[0.1, 0.9]), (20, ))

#returns 1 or 0

np.fromfunction(lambda i ,j : np.random.choice([0, 1], p=[0.1, 0.9]), (20, 1))

#still returns 1 or 0

Though I tried implementing "i" into the output stupidest way possible but.. it changed something, but still didn't help:

np.fromfunction(lambda i : i*0 + np.random.choice([0, 1], p=[0.1, 0.9]), (20, ))

#returns

array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

It's closer to the shape I want, but this ones or zeros are just repeated on all the array, so nothing's changed really.

To sum up: I have a function f() that generates randomly with some probability 0 and 1, and is there any other function in numpy that can repeat function f() on array, or maybe some way to repair the example above?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
newone
  • 23
  • 6
  • Weird to use [`np.fromfunction`](https://numpy.org/doc/stable/reference/generated/numpy.fromfunction.html) and use a function that doesn't rely on the `i` and `j`. Anyway, quoting the documentation: " If `function` returns a scalar value, the shape of fromfunction would not match the shape parameter.". The `function` is only called once, and `i` and `j` are arrays. – paime Mar 12 '23 at 20:44
  • So `f()` doesn't take any arguments? And returns just one number? Then call it repeatedly in a list comprehension. What's so difficult about that? `numpy` doesn't have any tool to "compile" your function. – hpaulj Mar 12 '23 at 21:23
  • @hpaulj the trick is that i need to use `numpy`, that's why i'm searching for resolution. Of course list comprehension would work or even `for` and `append`, but i searching for way without using both above. – newone Mar 12 '23 at 21:44
  • Why do you need to use `numpy`? This is a python function, right? It has to be called once for each generated number? – hpaulj Mar 12 '23 at 22:29
  • I just thought wanted to see everything that can be done with numpy, to see what is capable of. My task was to use as much as possible operation on arrays rather than build in functions. But thanks for help anyway – newone Mar 13 '23 at 09:16
  • `fromfunction` is well documented, and its source code is easy to read. If just calls `f(I,J)` where the `I,J` are coordinate arrays created by `np.indices`. `np.frompyfunc` and `np.vectorize` are functions that take a function with scalar inputs, and call it repeatedly. For small arrays they tend to be slower than the equivalent list comprehension, though they seem to scale somewhat better. Again, you need to read the docs. As the answer shows, it is possible to use `choice` in a way that returns many values. That's an example of using "numpy for everything". – hpaulj Mar 13 '23 at 15:35

2 Answers2

2

As @paime said in the comments, np.fromfunction is called once with the argument passed to it being an array. You can just use np.random.choice and specify size in it

In [1]: np.random.choice([0, 1], p=[0.1, 0.9], size=(20,))
Out[1]: array([1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1])
zaki98
  • 1,048
  • 8
  • 13
  • Is there a possibility to make that a modular function, where you can put some `f()` that returns 0 or 1 with it's own probability? – newone Mar 12 '23 at 21:04
1

Sure, np.random.choice([0, 1], p=[0.1, 0.9], size=(20,)) or also there is np.random.randint(low=0, high=2, size=(20,)).

HansQ
  • 380
  • 1
  • 7