Pandas фрейм данных случайным образом перемешивает некоторые значения столбцов в группах - PullRequest
1 голос
/ 20 марта 2020

Я бы хотел перемешать некоторые значения столбцов, но только внутри определенной группы и только с определенным процентом строк в группе. Например, для каждой группы я хочу перемешать n% значений в столбце b друг с другом.

df = pd.DataFrame({'grouper_col':[1,1,2,3,3,3,3,4,4], 'b':[12, 13, 16, 21, 14, 11, 12, 13, 15]})

   grouper_col   b
0            1  12
1            1  13
2            2  16
3            3  21
4            3  14
5            3  11
6            3  12
7            4  13
8            4  15

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

   grouper_col   b
0            1  13
1            1  12
2            2  16
3            3  21
4            3  11
5            3  14
6            3  12
7            4  15
8            4  13

Я нашел

df.groupby("grouper_col")["b"].transform(np.random.permutation)

но тогда я не могу контролировать процент перемешанных значений.

Спасибо за любые подсказки!

1 Ответ

1 голос
/ 20 марта 2020

Вы можете использовать numpy для создания такой функции (для ввода требуется массив numpy)

import numpy as np

def shuffle_portion(arr, percentage): 
    shuf = np.random.choice(np.arange(arr.shape[0]),  
                            round(arr.shape[0]*percentage/100), 
                            replace=False) 
    arr[np.sort(shuf)] = arr[shuf] 
    return arr

np.random.choice выберет набор индексов нужного вам размера. Тогда соответствующие значения в данном массиве могут быть переставлены в случайном порядке. Теперь это должно перемешать 3 значения из 9 в cloumn 'b'

df['b'] = shuffle_portion(df['b'].values, 33)

EDIT : для использования с apply необходимо преобразовать переданный кадр данных в массив внутри функции (объясняется в комментариях), а также создать возвращаемый фрейм данных

def shuffle_portion(_df, percentage=50): 
    arr = _df['b'].values
    shuf = np.random.choice(np.arange(arr.shape[0]),  
                            round(arr.shape[0]*percentage/100), 
                            replace=False) 
    arr[np.sort(shuf)] = arr[shuf] 
    _df['b'] = arr
    return _df

Теперь вы можете просто сделать

df.groupby("grouper_col", as_index=False).apply(shuffle_portion)

Было бы лучше, если вы передадите имя столбца, который нужно перетасовать, в функцию (def shuffle_portion(_df, col='b', percentage=50): arr = _df[col].values ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...