Вот сравнительно простой подход:
import random
STD_DEV = 2
integers = sorted([5, 5, 2, 4, 3, 1, 4, 5, 2, 3], reverse=True)
floats = sorted([0.1, 0.2, 0.3, 0.3, 0.3, 0.7, 0.6, 0.8, 0.5, 0.5])
results = []
for i in range(0, len(integers)):
noisy_index = min(max(int(random.gauss(i, STD_DEV)), 0), len(floats)-1)
results.append(floats[noisy_index])
print(results)
# [0.1, 0.2, 0.3, 0.2, 0.5, 0.3, 0.5, 0.5, 0.8, 0.7]
Сначала сортируются целые числа по убыванию, а затем по возрастанию с плавающей запятой, затем циклически перебираются по целочисленным индексам и определяют индекс значения с плавающей запятой для выборки из выборки из Гауссово распределение вокруг этого значения индекса. Значение STD_DEV даст вам контроль над тем, как часто будут выбираться другие индексы ... Я выбрал STD_DEV = 2, потому что он казался работоспособным (то есть маловероятно, что индекс = 0 будет переходить на индекс = 9).
Обратите внимание, что это действительно относительный подход к взвешиванию. Отсортированное целочисленное значение индекса - это то, что устанавливает наиболее вероятный плавающий элемент, который будет выбран, но он будет вести себя одинаково, если первые два числа будут 5, 5...
или если они будут 500, 5...
.
РЕДАКТИРОВАТЬ : если вы хотите, чтобы целочисленные значения имели некоторый вес, превосходящий их относительное упорядочение, одним из подходов будет масштабирование стандартного отклонения распределения Гасса на основе значения. Вот один из подходов (из многих способов сделать это), который просто масштабирует стандартное отклонение на основе расстояния от целочисленного значения до среднего:
import random
BASE_STD_DEV = 2
integers = sorted([5, 5, 2, 4, 3, 1, 4, 5, 2, 3], reverse=True)
floats = sorted([0.1, 0.2, 0.3, 0.3, 0.3, 0.7, 0.6, 0.8, 0.5, 0.5])
avg_int = sum(integers)/len(integers)
max_dist = max([abs(i - avg_int) for i in integers])
results = []
for i, integer in enumerate(integers):
factor = 1 - abs(integer - avg_int) / max_dist
std_dev = BASE_STD_DEV * factor
noisy_index = min(max(int(random.gauss(i, std_dev)), 0), len(floats)-1)
results.append(floats[noisy_index])
print(results)
# [0.1, 0.2, 0.3, 0.2, 0.5, 0.3, 0.5, 0.5, 0.8, 0.7]
Вы можете легко настроить это, чтобы, возможно, иметь минимум стандартное отклонение или минимальное / максимальное factor
, поскольку в настоящее время значения крайних значений не имеют стандартного отклонения.