Skip to main content
added 91 characters in body
Source Link
Graipher
  • 41.1k
  • 7
  • 69
  • 133

Python has an official style-guide, PEP8. It recommends using PascalCase for classes, so your class should be called Candidate. It also recommends using spaces after a , when passing multiple arguments to a function.

The creation of the candidates is as simple as this:

candidate_list = [Candidate() for _ in range(20000)]

Note that the starting index of range is 0 by default and that I used the customary variable name _ for the unused loop variable.

This also removes having to clear the candidates list, since it is being created anew every time you call the select function.

To get the candidate with the largest score, just use:

best_candidate = max(candidate_list, key=lambda c: c.total_score)

This does not allow you to easily remove them from the list of candidates, though. For this you can use enumerate:

index, candidate = max(enumerate(candidate_list), key=lambda t: t[1].total_score)

However, since you are running a not quite small numerical simulation, you might want to look into using numpy, which would greatly speed up the calculations. Instead of having a Candidate class, just create arrays. Generating random numbers in bulk is vastly faster than doing it one at a time as well:

import numpy as np

iterations = 100
candidates = 20000
top_ten_luck = []

for _ in range(iterations):
    scores = np.random.randint(0, 99, size=(candidates, 3))
    luck = np.random.randint(0, 100, size=candidates)
    total_score = 0.95 * scores.mean(axis=1) + 0.05 * luck
    top_ten = np.argpartition(-total_score, 10)[:10]
    top_ten_luck.extend(luck[top_ten])

print(np.mean(top_ten))

This runs in less than a second (132ms on my machine, to be exact). The for loop can also be vectorized, but at that point you might run into memory constraints.

Note that I used numpy.argpartition to get the indicies of the top ten candidates, in order to only partially sort the data as much as needed and not further. We need to use -total_score because it only gives you minimal values. This should be both faster than poping the maximum value ten times as well as completely sorting the list.

Python has an official style-guide, PEP8. It recommends using PascalCase for classes, so your class should be called Candidate.

The creation of the candidates is as simple as this:

candidate_list = [Candidate() for _ in range(20000)]

Note that the starting index of range is 0 by default and that I used the customary variable name _ for the unused loop variable.

This also removes having to clear the candidates list, since it is being created anew every time you call the select function.

To get the candidate with the largest score, just use:

best_candidate = max(candidate_list, key=lambda c: c.total_score)

This does not allow you to easily remove them from the list of candidates, though. For this you can use enumerate:

index, candidate = max(enumerate(candidate_list), key=lambda t: t[1].total_score)

However, since you are running a not quite small numerical simulation, you might want to look into using numpy, which would greatly speed up the calculations. Instead of having a Candidate class, just create arrays. Generating random numbers in bulk is vastly faster than doing it one at a time as well:

import numpy as np

iterations = 100
candidates = 20000
top_ten_luck = []

for _ in range(iterations):
    scores = np.random.randint(0, 99, size=(candidates, 3))
    luck = np.random.randint(0, 100, size=candidates)
    total_score = 0.95 * scores.mean(axis=1) + 0.05 * luck
    top_ten = np.argpartition(-total_score, 10)[:10]
    top_ten_luck.extend(luck[top_ten])

print(np.mean(top_ten))

This runs in less than a second (132ms on my machine, to be exact). The for loop can also be vectorized, but at that point you might run into memory constraints.

Note that I used numpy.argpartition to get the indicies of the top ten candidates, in order to only partially sort the data as much as needed and not further. We need to use -total_score because it only gives you minimal values. This should be both faster than poping the maximum value ten times as well as completely sorting the list.

Python has an official style-guide, PEP8. It recommends using PascalCase for classes, so your class should be called Candidate. It also recommends using spaces after a , when passing multiple arguments to a function.

The creation of the candidates is as simple as this:

candidate_list = [Candidate() for _ in range(20000)]

Note that the starting index of range is 0 by default and that I used the customary variable name _ for the unused loop variable.

This also removes having to clear the candidates list, since it is being created anew every time you call the select function.

To get the candidate with the largest score, just use:

best_candidate = max(candidate_list, key=lambda c: c.total_score)

This does not allow you to easily remove them from the list of candidates, though. For this you can use enumerate:

index, candidate = max(enumerate(candidate_list), key=lambda t: t[1].total_score)

However, since you are running a not quite small numerical simulation, you might want to look into using numpy, which would greatly speed up the calculations. Instead of having a Candidate class, just create arrays. Generating random numbers in bulk is vastly faster than doing it one at a time as well:

import numpy as np

iterations = 100
candidates = 20000
top_ten_luck = []

for _ in range(iterations):
    scores = np.random.randint(0, 99, size=(candidates, 3))
    luck = np.random.randint(0, 100, size=candidates)
    total_score = 0.95 * scores.mean(axis=1) + 0.05 * luck
    top_ten = np.argpartition(-total_score, 10)[:10]
    top_ten_luck.extend(luck[top_ten])

print(np.mean(top_ten))

This runs in less than a second (132ms on my machine, to be exact). The for loop can also be vectorized, but at that point you might run into memory constraints.

Note that I used numpy.argpartition to get the indicies of the top ten candidates, in order to only partially sort the data as much as needed and not further. We need to use -total_score because it only gives you minimal values. This should be both faster than poping the maximum value ten times as well as completely sorting the list.

added 35 characters in body
Source Link
Graipher
  • 41.1k
  • 7
  • 69
  • 133

Python has an official style-guide, PEP8. It recommends using PascalCase for classes, so your class should be called Candidate.

The creation of the candidates is as simple as this:

candidate_list = [Candidate() for _ in range(20000)]

Note that the starting index of range is 0 by default and that I used the customary variable name _ for the unused loop variable.

This also removes having to clear the candidates list, since it is being created anew every time you call the select function.

To get the candidate with the largest score, just use:

best_candidate = max(candidate_list, key=lambda c: c.total_score)

This does not allow you to easily remove them from the list of candidates, though. For this you can use enumerate:

index, candidate = max(enumerate(candidate_list), key=lambda t: t[1].total_score)

However, since you are running a not quite small numerical simulation, you might want to look into using numpy, which would greatly speed up the calculations. Instead of having a Candidate class, just create arrays. Generating random numbers in bulk is vastly faster than doing it one at a time as well:

import numpy as np

iterations = 100
candidates = 20000
top_ten_luck = []

for _ in range(iterations):
    scores = np.random.randint(0, 99, size=(candidates, 3))
    luck = np.random.randint(0, 100, size=candidates)
    total_score = 0.95 * scores.mean(axis=1) + 0.05 * luck
    top_ten = np.argpartition(-total_score, 10)[:10]
    top_ten_luck.extend(luck[top_ten])

print(np.mean(top_ten))

This runs in less than a second (132ms on my machine, to be exact). The for loop can also be vectorized, but at that point you might run into memory constraints.

Note that I used numpy.argpartition to get the indicies of the top ten candidates, in order to only partially sort the data as much as needed and not further. We need to use -total_score because it only gives you minimal values. This should be both faster than poping the maximum value ten times as well as completely sorting the list.

Python has an official style-guide, PEP8. It recommends using PascalCase for classes, so your class should be called Candidate.

The creation of the candidates is as simple as this:

candidate_list = [Candidate() for _ in range(20000)]

Note that the starting index of range is 0 by default and that I used the customary variable name _ for the unused loop variable.

This also removes having to clear the candidates list, since it is being created anew every time you call the select function.

To get the candidate with the largest score, just use:

best_candidate = max(candidate_list, key=lambda c: c.total_score)

This does not allow you to easily remove them from the list of candidates, though. For this you can use enumerate:

index, candidate = max(enumerate(candidate_list), key=lambda t: t[1].total_score)

However, since you are running a not quite small numerical simulation, you might want to look into using numpy, which would greatly speed up the calculations. Instead of having a Candidate class, just create arrays. Generating random numbers in bulk is vastly faster than doing it one at a time as well:

import numpy as np

iterations = 100
candidates = 20000
top_ten_luck = []

for _ in range(iterations):
    scores = np.random.randint(0, 99, size=(candidates, 3))
    luck = np.random.randint(0, 100, size=candidates)
    total_score = 0.95 * scores.mean(axis=1) + 0.05 * luck
    top_ten = np.argpartition(-total_score, 10)[:10]
    top_ten_luck.extend(luck[top_ten])

print(np.mean(top_ten))

This runs in less than a second. The for loop can also be vectorized, but at that point you might run into memory constraints.

Note that I used numpy.argpartition in order to only partially sort the data as much as needed. We need to use -total_score because it only gives you minimal values.

Python has an official style-guide, PEP8. It recommends using PascalCase for classes, so your class should be called Candidate.

The creation of the candidates is as simple as this:

candidate_list = [Candidate() for _ in range(20000)]

Note that the starting index of range is 0 by default and that I used the customary variable name _ for the unused loop variable.

This also removes having to clear the candidates list, since it is being created anew every time you call the select function.

To get the candidate with the largest score, just use:

best_candidate = max(candidate_list, key=lambda c: c.total_score)

This does not allow you to easily remove them from the list of candidates, though. For this you can use enumerate:

index, candidate = max(enumerate(candidate_list), key=lambda t: t[1].total_score)

However, since you are running a not quite small numerical simulation, you might want to look into using numpy, which would greatly speed up the calculations. Instead of having a Candidate class, just create arrays. Generating random numbers in bulk is vastly faster than doing it one at a time as well:

import numpy as np

iterations = 100
candidates = 20000
top_ten_luck = []

for _ in range(iterations):
    scores = np.random.randint(0, 99, size=(candidates, 3))
    luck = np.random.randint(0, 100, size=candidates)
    total_score = 0.95 * scores.mean(axis=1) + 0.05 * luck
    top_ten = np.argpartition(-total_score, 10)[:10]
    top_ten_luck.extend(luck[top_ten])

print(np.mean(top_ten))

This runs in less than a second (132ms on my machine, to be exact). The for loop can also be vectorized, but at that point you might run into memory constraints.

Note that I used numpy.argpartition to get the indicies of the top ten candidates, in order to only partially sort the data as much as needed and not further. We need to use -total_score because it only gives you minimal values. This should be both faster than poping the maximum value ten times as well as completely sorting the list.

deleted 9 characters in body
Source Link
Graipher
  • 41.1k
  • 7
  • 69
  • 133

Python has an official style-guide, PEP8PEP8. It recommends using PascalCase for classes, so your class should be called Candidate.

The creation of the candidates should beis as simple as this:

candidate_list = [Candidate() for _ in range(20000)]

Note that the starting index of range is 0 by default and that I used the customary variable name _ for the unused loop variable.

This also removes having to clear the candidates list, since it is being created anew every time you call the select function.

To get the candidate with the largest score, just use:

best_candidate = max(candidate_list, key=lambda c: c.total_score)

This does not allow you to easily remove them from the list of candidates, though. For this you can use enumerate:

index, candidate = max(enumerate(candidate_list), key=lambda t: t[1].total_score)

However, since you are running a not quite small numerical simulation, you might want to look into using numpy, which would greatly speed up the calculations. Instead of having a Candidate class, just create arrays. Generating random numbers in bulk is vastly faster than doing it one at a time as well:

import numpy as np

iterations = 100
candidates = 20000
top_ten_luck = []

for _ in range(iterations):
    scores = np.random.randint(0, 99, size=(candidates, 3))
    luck = np.random.randint(0, 100, size=candidates)
    total_score = 0.95 * scores.mean(axis=1) + 0.05 * luck
    top_ten = np.argpartition(-total_score, 10)[:10]
    top_ten_luck.extend(luck[top_ten])

print(np.mean(top_ten))

This runs in less than a second. The for loop can probably also be vectorized, but at that point you might run into memory constraints.

Note that I used numpy.argpartition in order to only partially sort the data as much as needed. We need to use -total_score because it only gives you minimal values.

Python has an official style-guide, PEP8. It recommends using PascalCase for classes, so your class should be called Candidate.

The creation of the candidates should be as simple as this:

candidate_list = [Candidate() for _ in range(20000)]

Note that the starting index of range is 0 by default.

This also removes having to clear the candidates list, since it is being created anew every time you call the select function.

To get the candidate with the largest score, just use:

best_candidate = max(candidate_list, key=lambda c: c.total_score)

This does not allow you to easily remove them from the list of candidates, though. For this you can use enumerate:

index, candidate = max(enumerate(candidate_list), key=lambda t: t[1].total_score)

However, since you are running a not quite small numerical simulation, you might want to look into using numpy, which would greatly speed up the calculations. Instead of having a Candidate class, just create arrays. Generating random numbers in bulk is vastly faster than doing it one at a time as well:

import numpy as np

iterations = 100
candidates = 20000
top_ten_luck = []

for _ in range(iterations):
    scores = np.random.randint(0, 99, size=(candidates, 3))
    luck = np.random.randint(0, 100, size=candidates)
    total_score = 0.95 * scores.mean(axis=1) + 0.05 * luck
    top_ten = np.argpartition(-total_score, 10)[:10]
    top_ten_luck.extend(luck[top_ten])

print(np.mean(top_ten))

This runs in less than a second. The for loop can probably also be vectorized, but at that point you might run into memory constraints.

Note that I used numpy.argpartition in order to only partially sort the data as much as needed. We need to use -total_score because it only gives you minimal values.

Python has an official style-guide, PEP8. It recommends using PascalCase for classes, so your class should be called Candidate.

The creation of the candidates is as simple as this:

candidate_list = [Candidate() for _ in range(20000)]

Note that the starting index of range is 0 by default and that I used the customary variable name _ for the unused loop variable.

This also removes having to clear the candidates list, since it is being created anew every time you call the select function.

To get the candidate with the largest score, just use:

best_candidate = max(candidate_list, key=lambda c: c.total_score)

This does not allow you to easily remove them from the list of candidates, though. For this you can use enumerate:

index, candidate = max(enumerate(candidate_list), key=lambda t: t[1].total_score)

However, since you are running a not quite small numerical simulation, you might want to look into using numpy, which would greatly speed up the calculations. Instead of having a Candidate class, just create arrays. Generating random numbers in bulk is vastly faster than doing it one at a time as well:

import numpy as np

iterations = 100
candidates = 20000
top_ten_luck = []

for _ in range(iterations):
    scores = np.random.randint(0, 99, size=(candidates, 3))
    luck = np.random.randint(0, 100, size=candidates)
    total_score = 0.95 * scores.mean(axis=1) + 0.05 * luck
    top_ten = np.argpartition(-total_score, 10)[:10]
    top_ten_luck.extend(luck[top_ten])

print(np.mean(top_ten))

This runs in less than a second. The for loop can also be vectorized, but at that point you might run into memory constraints.

Note that I used numpy.argpartition in order to only partially sort the data as much as needed. We need to use -total_score because it only gives you minimal values.

Source Link
Graipher
  • 41.1k
  • 7
  • 69
  • 133
Loading