Python: перемешать массив строк, включая дубликаты, сохраняя при этом распределение элементов - PullRequest
1 голос
/ 11 июля 2019

У меня есть массив строк, которые могут включать в себя дублированные записи.Мне нужно случайным образом переназначить каждую уникальную строку всем местоположениям другой случайно выбранной строки в массиве, учитывая, что строка с несколькими исходными местоположениями может быть сопоставлена ​​с одним новым местоположением, и наоборот.По сути, я переназначаю ключи в массиве, но сохраняю оригинальное распределение ключей.

У меня есть работающая реализация Pandas & numpy, которая работает для смешанных типов ввода, но она неэффективна в масштабе, так какперебирает каждое уникальное значение (мне нужно, чтобы оно работало эффективно для минимума значений 1м +, в идеале больше).Медленный бит здесь - это само перечисление:

def shuffle_fields(series):
    # Create a copy of the original series.
    _series = series.copy()

    # Get non-NaN keys of original data.
    keys = series[pd.notnull(_series)].unique()

    # Create a copy of these keys.
    _keys = np.copy(keys)

    # Shuffle the copy.
    np.random.shuffle(_keys)

    # Iterate over all zipped keys and set values in copy of series.
    for i, (val, new) in enumerate(zip(keys, _keys)):

        # Need to key off series as _series is being changed during the loop.
        _series.loc[series == val] = new

    return _series

Пример ввода:

_input = pd.Series(['One', 'One', np.NaN, 2, np.NaN, True, 2, 2, 'One', 'One'])

Ожидаемый результат:

output = pd.Series([2, 2, np.NaN, True, np.NaN, 'One', True, True, 2, 2])

Открыт для предложений по любой реализации, которая будетработать в масштабе.Я не обязан чему-то, что будет работать со смешанными типами данных (как в примере выше), но это хороший бонус.Техника должна быть способна обрабатывать значения NULL / NaN, т.е. значения NaN должны оставаться неизменными.

1 Ответ

1 голос
/ 11 июля 2019

Это работает при условии, что вы можете сравнить на равенство на основе строкового представления объектов:

import numpy as np
import pandas as pd

np.random.seed(0)
_input = pd.Series(['One', 'One', np.NaN, 2, np.NaN, True, 2, 2, 'One', 'One'])
v = _input.values
uniq, idx = np.unique(v.astype(str), return_inverse=True)
r = np.random.permutation(len(uniq))
output = pd.Series(uniq[r[idx]])
print(output)
# 0     nan
# 1     nan
# 2       2
# 3    True
# 4       2
# 5     One
# 6    True
# 7    True
# 8     nan
# 9     nan
# dtype: object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...