Python:在保持项目分配的同时,重新排列包括重复项在内的字符串数组

时间:2019-07-11 17:37:43

标签: python python-3.x pandas numpy

我有一个字符串数组,可以包含重复的条目。我需要将每个唯一字符串随机地重新分配给数组中另一个随机选择的字符串的所有位置,请记住,具有多个原始位置的字符串可以映射到一个新位置,反之亦然。实际上,我是在数组中重新分配键,但要保留键的原始分布。

我有一个适用于混合输入类型的有效的Pandas&numpy实现,但是在遍历每个唯一值时,它在规模上效率不高(我将要求它在最小1m +值(最好是更多)上有效地工作)。这里最慢的是枚举本身:

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 个答案:

答案 0 :(得分:1)

如果您可以根据对象的字符串表示形式比较相等性,则可以使用此功能

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