Случайный выбор% элементов в строке и изменение значения - PullRequest
0 голосов
/ 26 октября 2018

У меня есть массив строковых значений, и мне нужно пройти через них, чтобы случайным образом заменить 5% элементов в каждом, и перевернуть их на 0, если они равны 1, и перевернуть их на 1, если они равны 0.

У меня есть массив строковых значений, который выглядит следующим образом:

['10011000000100000000011101100010001000110111101100100101100000111010000110011111001101001110100111110110000110001001010001010001110000000000000111110000111100010011101001011001111111011010001001100100110110000001000001010100111111110010011001100001001100011001111010010011000101000101111001100000110011101100000010110111011000010001111011010000111010100001101011000110111000000010000000111100010100100110101101111011001010000001110010110100011110000010001101110001101000100011001110101000100011111010',
 '11010000000110110011011110111010011011111010000101101101111010101000100000001010011100011011101111001000100000011110000011001100101011100111111001001101111110001101001100010111000100100010010111001110010110010101010110100000110011011110100110010011110000101001111111001001001101011000111001101101011000111101010010000011001001011110011010101111110001010100001011000001011110001011100100010011001101111100001111101000000010001010001100001010000010000000000001010101001110110111000010010001001001010101',
 '10011000000100000000011101100010001000110111101100100101100000111010000110011111001101001110100111110110000110001001010001010001110000000000000111110000111100010011101001011001111111011010001001000001011010100011000101000001100101000101010000001100111100101000011010000001011000000000000000011010100111100111010001111010000101100101010000110011111011111110100011111000001110111111001011011111101011110100000011101101101110010101001010100110111010000111000000111000110010110110001101111010011110000111',
 '11010000000110110011011110111010011011111010000101101101111010101000100000001010011100011011101111001000100000011110000011001100101011100111111001001101111110001101001100010111000100100010010111001110010110010101010110100000110011011110100110010011110000101001111111001001001101011000111001101101011000111101010010011100101111001010010000010010101101001000001111010110000111110100100001101101111011110101001000001101101100110110001110011000010000110110011100100001001101011010101100010011110111000000']

Фактически, 5% значений в строке изменится с 0 на 1 или наоборот.

Ответы [ 3 ]

0 голосов
/ 26 октября 2018

Попробуйте этот цикл:

for idx,i in enumerate(l):
    y=list(i)
    for x in random.sample(range(len(i)),(len(i)*5)//100):
        y[x]=str(abs(int(y[x])-1))
    l[idx]=''.join(y)

Переворачивается от одного до нуля и наоборот, и только 5% из них.

0 голосов
/ 26 октября 2018

Чтобы эффективно генерировать новый массив строк, вы должны избегать изменения строки при каждом измененном изменении. Таким образом, я предоставляю свое решение (method2), которое может быть более оптимизировано при необходимости.

method 1 и 2 близки, различие заключается в использовании списка понимания вместо цикла for.

method 3 медленнее, поскольку время, необходимое для генерации модифицированной строки длиной 500, короче, чем время для порождения потока. но для более длинной строки этот метод может быть самым быстрым.

Метод 4 взят из U9-Forward

#!/usr/bin/env python3
import random
import timeit
from typing import List
from multiprocessing.pool import Pool
from statistics import mean


def get_partial_str(my_binary_string: str, mutated_bit):
    start = 0
    for index, bit_value in mutated_bit:
        yield my_binary_string[start:index] + str(bit_value)
        start = index + 1
    if index != len(my_binary_string):
        yield my_binary_string[start:]


def replace_x_percent(my_binary_string: str, percent: float):
    nb__bit_to_replace = int(percent * len(my_binary_string))
    index_to_mutate = sorted(
        random.sample(range(len(my_binary_string)), nb__bit_to_replace))
    mutated_bit = map(lambda x: (x, 0) if my_binary_string[x] == 1 else (x, 1),
                      index_to_mutate)
    return ''.join(( partial_bit_str for partial_bit_str in  get_partial_str(my_binary_string, mutated_bit)))


def method1(arr: List[str]):
    for i, my_binary_string in enumerate(arr):
        arr[i] = replace_x_percent(my_binary_string, 0.05)
    return arr


def method2(arr: List[str]):
    arr = [replace_x_percent(my_binary_string, 0.05)
           for my_binary_string in arr]
    return arr


def method3(arr: List[str]):
    with Pool(processes=4) as pool:
        arr = pool.starmap(replace_x_percent, ((my_binary_string, 0.05)
                                               for my_binary_string in arr))
    return arr


def method4(arr: List[str]):
    for idx, i in enumerate(arr):
        y = list(i)
        for x in random.sample(range(len(i)), len(i) // 5):
            y[x] = str(abs(int(y[x]) - 1))
        arr[idx] = ''.join(y)
    return arr


if __name__ == '__main__':
    arr = [
        '10011000000100000000011101100010001000110111101100100101100000111010000110011111001101001110100111110110000110001001010001010001110000000000000111110000111100010011101001011001111111011010001001100100110110000001000001010100111111110010011001100001001100011001111010010011000101000101111001100000110011101100000010110111011000010001111011010000111010100001101011000110111000000010000000111100010100100110101101111011001010000001110010110100011110000010001101110001101000100011001110101000100011111010',
        '11010000000110110011011110111010011011111010000101101101111010101000100000001010011100011011101111001000100000011110000011001100101011100111111001001101111110001101001100010111000100100010010111001110010110010101010110100000110011011110100110010011110000101001111111001001001101011000111001101101011000111101010010000011001001011110011010101111110001010100001011000001011110001011100100010011001101111100001111101000000010001010001100001010000010000000000001010101001110110111000010010001001001010101',
        '10011000000100000000011101100010001000110111101100100101100000111010000110011111001101001110100111110110000110001001010001010001110000000000000111110000111100010011101001011001111111011010001001000001011010100011000101000001100101000101010000001100111100101000011010000001011000000000000000011010100111100111010001111010000101100101010000110011111011111110100011111000001110111111001011011111101011110100000011101101101110010101001010100110111010000111000000111000110010110110001101111010011110000111',
        '11010000000110110011011110111010011011111010000101101101111010101000100000001010011100011011101111001000100000011110000011001100101011100111111001001101111110001101001100010111000100100010010111001110010110010101010110100000110011011110100110010011110000101001111111001001001101011000111001101101011000111101010010011100101111001010010000010010101101001000001111010110000111110100100001101101111011110101001000001101101100110110001110011000010000110110011100100001001101011010101100010011110111000000']

    print( 'Starting the benchmark:' )
    t1 = mean(timeit.repeat('method1(arr)', number=1, repeat=10, globals=globals()))
    print('- method 1: {:.5f}'.format(t1))
    t2 = mean(timeit.repeat('method2(arr)', number=1, repeat=10, globals=globals()))
    print('- method 2: {:.5f}'.format(t2))
    t3 = mean(timeit.repeat('method3(arr)', number=1, repeat=10, globals=globals()))
    print('- method 3: {:.5f}'.format(t3))
    t4 = mean(timeit.repeat('method4(arr)', number=1, repeat=10, globals=globals()))
    print('- method 4: {:.5f}'.format(t4))
#!/usr/bin/env python3
import random
import timeit
from typing import List
from multiprocessing.pool import Pool
from statistics import mean


def get_partial_str(my_binary_string: str, mutated_bit):
    start = 0
    for index, bit_value in mutated_bit:
        yield my_binary_string[start:index] + str(bit_value)
        start = index + 1
    if index != len(my_binary_string):
        yield my_binary_string[start:]


def replace_x_percent(my_binary_string: str, percent: float):
    nb__bit_to_replace = int(percent * len(my_binary_string))
    index_to_mutate = sorted(
        random.sample(range(len(my_binary_string)), nb__bit_to_replace))
    mutated_bit = map(lambda x: (x, 0) if my_binary_string[x] == 1 else (x, 1),
                      index_to_mutate)
    return ''.join(( partial_bit_str for partial_bit_str in  get_partial_str(my_binary_string, mutated_bit)))


def method1(arr: List[str]):
    for i, my_binary_string in enumerate(arr):
        arr[i] = replace_x_percent(my_binary_string, 0.05)
    return arr


def method2(arr: List[str]):
    arr = [replace_x_percent(my_binary_string, 0.05)
           for my_binary_string in arr]
    return arr


def method3(arr: List[str]):
    with Pool(processes=4) as pool:
        arr = pool.starmap(replace_x_percent, ((my_binary_string, 0.05)
                                               for my_binary_string in arr))
    return arr


def method4(arr: List[str]):
    for idx, i in enumerate(arr):
        y = list(i)
        for x in random.sample(range(len(i)), len(i) // 5):
            y[x] = str(abs(int(y[x]) - 1))
        arr[idx] = ''.join(y)
    return arr


if __name__ == '__main__':
    arr = [
        '10011000000100000000011101100010001000110111101100100101100000111010000110011111001101001110100111110110000110001001010001010001110000000000000111110000111100010011101001011001111111011010001001100100110110000001000001010100111111110010011001100001001100011001111010010011000101000101111001100000110011101100000010110111011000010001111011010000111010100001101011000110111000000010000000111100010100100110101101111011001010000001110010110100011110000010001101110001101000100011001110101000100011111010',
        '11010000000110110011011110111010011011111010000101101101111010101000100000001010011100011011101111001000100000011110000011001100101011100111111001001101111110001101001100010111000100100010010111001110010110010101010110100000110011011110100110010011110000101001111111001001001101011000111001101101011000111101010010000011001001011110011010101111110001010100001011000001011110001011100100010011001101111100001111101000000010001010001100001010000010000000000001010101001110110111000010010001001001010101',
        '10011000000100000000011101100010001000110111101100100101100000111010000110011111001101001110100111110110000110001001010001010001110000000000000111110000111100010011101001011001111111011010001001000001011010100011000101000001100101000101010000001100111100101000011010000001011000000000000000011010100111100111010001111010000101100101010000110011111011111110100011111000001110111111001011011111101011110100000011101101101110010101001010100110111010000111000000111000110010110110001101111010011110000111',
        '11010000000110110011011110111010011011111010000101101101111010101000100000001010011100011011101111001000100000011110000011001100101011100111111001001101111110001101001100010111000100100010010111001110010110010101010110100000110011011110100110010011110000101001111111001001001101011000111001101101011000111101010010011100101111001010010000010010101101001000001111010110000111110100100001101101111011110101001000001101101100110110001110011000010000110110011100100001001101011010101100010011110111000000']

    print( 'Starting the benchmark:' )
    t1 = mean(timeit.repeat('method1(arr)', number=1, repeat=10, globals=globals()))
    print('- method 1: {:.5f}'.format(t1))
    t2 = mean(timeit.repeat('method2(arr)', number=1, repeat=10, globals=globals()))
    print('- method 2: {:.5f}'.format(t2))
    t3 = mean(timeit.repeat('method3(arr)', number=1, repeat=10, globals=globals()))
    print('- method 3: {:.5f}'.format(t3))
    t4 = mean(timeit.repeat('method4(arr)', number=1, repeat=10, globals=globals()))
    print('- method 4: {:.5f}'.format(t4))

Результаты:

Starting the benchmark:
- method 1: 0.00038
- method 2: 0.00034
- method 3: 0.11711
- method 4: 0.00207
0 голосов
/ 26 октября 2018

Используйте random.choices, чтобы получить индексы для 5%

import random
[[i for i in random.choices(range(len(arr[j])), k=int(len(arr[j]) * 0.05))] for j in range(len(arr))]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...