how to choose the independently weighted numbers in Python? - python

import random
number=list(range(1,10))
weighted=[1]*2+[2]*2+[3]*2+[4]*2+[5]*2
number_weighted=random.choice(number,weighted,k=1) **#if k=4 then the same number is chosen sometimes**
I want to use loop 3 times to choose the each one number.
I want to choose the number that independent(not same), weighted.
In python, if you know this problem, I would appreciate it if you taught me
For example,
number=[1,2,3,4,5]
weighted=[0.1,0.1,0.4,0.3,0.1]
then choose two number
i want 3, 4 Probability)
but random.choice function is sometimes 1,1 selected.
so, i think
i take one number (suppose number 3) then
number=[1,2,4,5]
weighted=[0.1,0.1,0.3,0.1]
and i take one number (suppose number 4). use loop function

Your question isn't quite clear, so comment if it doesn't solve your problem.
Define functionn which returns random from the list and weight. another function to make sure you have n randoms from different weights.
And your weight and array was of different length I hope that was an error.
import random
def get_rand(num_list,weight_list,weight):
selection_from= [i for i,v in enumerate(weight_list) if v==weight]
print(selection_from)
rand_index =random.choice(selection_from)
return num_list[rand_index]
def get_n_rand(num_list,weight_list,n):
weights= list(set(weight_list))
random.shuffle(weights)
final_list=[]
# if you don't want numbers from same weight
for weight in weights[:n]:
final_list.append(get_rand(num_list,weight_list,weight))
#if same weight is also fine use this:
#for i in range(n):
# weight = random.choice(weights)
# final_list.append(get_rand(num_list,weight_list,weight))
return final_list
number=list(range(1,10))
weighted=[1]*2+[2]*2+[3]*2+[4]*2+[5]*1
assert(len(number)==len(weighted))
rand=get_n_rand(number,weighted,3)
print("selected numbers:",rand)
print("their weights:",[weighted[number.index(i)] for i in rand])
Since you had hard time understanding,
selection_from= [i for i,v in enumerate(weight_list) if v==weight]
is equivalent to:
selection_from= []
for i in range(len(weight_list)):
v= weight_list[i]
if v==weight:
selection_from.append(i)

Related

Random sample without repetition but probability

I am somehow missing a function in python which is a combination of two I know.
I have a list of numbers and probabilities for those and want to chose n of them, without repetition.
random.sample can chose from a list without repetition, but does not allow probabilities:
l = [5,124,6,2,7,1]
sample(l,k=5)
On the other hand, choices allows me to use weights, but uses repetition:
choices(l,k=2,weights=[0.5,0.25,0.25,0.125,0,0.125])
Is there any chance how do to that in combination?
Until now I run a while-loop doing choices so often until the number of uniquely chosen elements becomes k. But this is quite inefficient, in particular of one element has big probability.
numpy.random.choice works. Use:
import numpy as np
l = [5,124,6,2,7,1]
weights=[0.5,0.25,0.25,0.125,0,0.125]
weights = [w/sum(weights) for w in weights]
np.random.choice(l, size=5, replace=False, p=weights)
Edited to make probabilities sum to 1

python random number generator for long list of numbers

I was wondering if anyone could help me write a better program. My goal is to make a random number generatorm but it has very specific perameters. I need to find a random number that looks for a random number for unit numbers in a housing compley. the parameters are between 101-112, 114-125, 128-149, 201-230, 232-263, 265-280 and 300-305. I made a list with every number and then called the random number function, but I was just wondering if there was an easier way or a more concise way to make this program. Thank you!
In order to make sure that your choice is equiprobable, your could start by choosing among your ranges with weights equal to the number of values in each range. random.choices allows you to specify weights.
You can then simply choose any value in the selected range:
import random
def random_in_ranges(ranges):
weights = [end - start + 1 for start, end in ranges]
range_ = random.choices(ranges, weights=weights)[0]
return random.randint(*range_)
ranges = [(101,112), (114,125), (128,149), (201,230), (232,263), (265,280), (300,305)]
print(random_in_ranges(ranges))
# 262
I think you should use
flat_num = random.choise(flats)
if you have your number in some Iterable struct
or
you can random range and then select from selected range if you have just a numbers like this:
flat_num = random.randint(
*random.choice(
[(101,112),(114,125),(128,149),(201-230),(232-263),(300-305)]
)
)

Fredo and Array Update in python

I will have an interview with a company which like the hackerearth.com. I don't know how to work and doing the code perfectly. Could you help me with the following example?
This is the example for the .hackerearth.com, however, I don't know that I should consider the constraint in the code? can I use a package like NumPy? or I should only use the basic calculation with my self? Could you check my response and let me know the problem with that? Thank you so much
Input Format:
First line of input consists of an integer N denoting the number of elements in the array A.
Second line consists of N space separated integers denoting the array elements.
Output Format:
The only line of output consists of the value of x.
Input Constraints:
1<N<100
1<A[i]<100
explanation:
An initial sum of array is 1+2+3+4+5=15
When we update all elements to 4, the sum of array which is greater than 15 .
Note that if we had updated the array elements to 3, which is not greater than 15 . So, 4 is the minimum value to which array elements need to be updated.
# Write your code here
import numpy as np
A= [1, 2, 3,4,5]
for i in range(1, max(A)+1):
old = sum(A)
new = sum(i*np.ones(len(A)))
diff = new-old
if diff>0:
print(i)
break
Well this isn't Code Review stack exchange, but:
You don't say how to calculate x. It seems to be something to do with finding an average value, but no-one can judge your code without know what it's trying to do. A web search suggests it is this:
Fredo is assigned a new task today. He is given an array A containing N integers. His task is to update all elements of array to some minimum value x , that is, ; such that sum of this new array is strictly greater than the sum of the initial array. Note that x should be as minimum as possible such that sum of the new array is greater than the sum of the initial array.
Given that the task starts by accepting input, it's important that your program does this part.
N = int(input()) # you can put a prompt string in here, but may conflict with limited output
A = list(map(int,input().split()))
# might need input checks
# might need range checks
# might check that A has exactly N values
you don't need to recalculate old = sum(A) every time around your search loop
calculation of new doesn't need a sum at all - it's just new = i * len(A)
there's no point in checking values of i at or below min(A)
your search will fail if all values of A are the same (try it), because you never look above max(A)
These remarks apply to your approach; a more efficient search would be binary chop, and there is also a mathematical way to go straight to the answer from sum(A) without any searching:
x = sum(A) // len(A) + 1
You don't need numpy or looping for this. Get the average of the array elements, then get the next higher integer from this.
N = 5
A = [1, 2, 3, 4, 5]
total = sum(A)
avg = A/N # not checking for zero-divide because conditions say N > 1
x = floor(avg + 1)
print(x)
Adding 1 is necessary to make the new sum greater than the original sum when the average is an exact integer (e.g. 15/5 == 3).

List's and while loops - Python

I am fairly new to Python and I am stuck on a particular question and I thought i'd ask you guys.
The following contains my code so far, aswell as the questions that lie therein:
list=[100,20,30,40 etc...]
Just a list with different numeric values representing an objects weight in grams.
object=0
while len(list)>0:
list_caluclation=list.pop(0)
print(object number:",(object),"evaluates to")
What i want to do next is evaluate the items in the list. So that if we go with index[0], we have a list value of 100. THen i want to separate this into smaller pieces like, for a 100 gram object, one would split it into five 20 gram units. If the value being split up was 35, then it would be one 20 gram unit, on 10 gram unit and one 5 gram unit.
The five units i want to split into are: 20, 10, 5, 1 and 0.5.
If anyone has a quick tip regarding my issue, it would be much appreciated.
Regards
You should think about solving this for a single number first. So what you essentially want to do is split up a number into a partition of known components. This is also known as the Change-making problem. You can choose a greedy algorithm for this that always takes the largest component size as long as it’s still possible:
units = [20, 10, 5, 1, 0.5]
def change (number):
counts = {}
for unit in units:
count, number = divmod(number, unit)
counts[unit] = count
return counts
So this will return a dictionary that maps from each unit to the count of that unit required to get to the target number.
You just need to call that function for each item in your original list.
One way you could do it with a double for loop. The outer loop would be the numbers you input and the inner loop would be the values you want to evaluate (ie [20,10,5,1,0.5]). For each iteration of the inner loop, find how many times the value goes into the number (using the floor method), and then use the modulo operator to reassign the number to be the remainder. On each loop you can have it print out the info that you want :) Im not sure exactly what kind of output you're looking for, but I hope this helps!
Ex:
import math
myList=[100,20,30,40,35]
values=[20,10,5,1,0.5]
for i in myList:
print(str(i)+" evaluates to: ")
for num in values:
evaluation=math.floor(i/num)
print("\t"+str(num)+"'s: "+str(evaluation))
i%=num

Python-random number and its frequency

The function randint from the random module can be used to produce random numbers. A call on random.randint(1, 6), for example, will produce the values 1 to 6 with equal probability. Write a program that loops 1000 times. On each iteration it makes two calls on randint to simulate rolling a pair of dice. Compute the sum of the two dice, and record the number of times each value appears.
The output should be two columns. One displays all the sums (i.e. from 2 to 12) and the other displays the sums' respective frequencies in 1000 times.
My code is shown below:
import random
freq=[0]*13
for i in range(1000):
Sum=random.randint(1,6)+random.randint(1,6)
#compute the sum of two random numbers
freq[sum]+=1
#add on the frequency of a particular sum
for Sum in xrange(2,13):
print Sum, freq[Sum]
#Print a column of sums and a column of their frequencies
However, I didn't manage to get any results.
You shouldn't use Sum because simple variables should not be capitalized.
You shouldn't use sum because that would shadow the built-in sum().
Use a different non-capitalized variable name. I suggest diceSum; that's also stating a bit about the context, the idea behind your program etc. so a reader understands it faster.
You don't want to make any readers of your code happy? Think again. You asked for help here ;-)
Try this:
import random
freq=[0]*13
for i in range(1000):
Sum=random.randint(1,6)+random.randint(1,6)
#compute the sum of two random numbers
freq[Sum]+=1
#add on the frequency of a particular sum
for Sum in xrange(2,13):
print Sum, freq[Sum]
#Print a column of sums and a column of their frequencies
There's a grammar case error on sum
The seed generator that python uses should suffice to your task.
Looks like a typo error. Sum variable is wrongly typed as sum.
Below is the modified code in python 3.x
#!/usr/bin/env python3
import random
freq= [0]*13
for i in range(1000):
#compute the sum of two random numbers
Sum = random.randint(1,6)+random.randint(1,6)
#add on the frequency of a particular sum
freq[Sum] += 1
for Sum in range(2,13):
#Print a column of sums and a column of their frequencies
print(Sum, freq[Sum])

Categories

Resources