У меня есть столбец sites в pandas df. Формат данных: список строк. Мне нужно изменить значения столбца на случайно сгенерированные слова. Мои данные ниже:

row                    sites
1                    ["Elle", "Harpers", "Cosmo"]
2                    ["Elle", "Vogue"]
3                    ["Cosmo"]

Пожеланная выходная мощность:

row                    sites
1                     ["KLD", "GHL", "JGF"]
2                     ["KLD", "VGO"]
3                     ["JGF"]

Я должен иметь возможность перевернуть имена после также или сохранить их в формате VGO = Vogue Я хотел использовать numpy.random.randint, но похоже, что этот метод предназначен только для целых чисел. Каков самый быстрый способ сгенерировать имена вместо жесткого кода с помощью replace?

1
Chique_Code 1 Сен 2020 в 00:52

2 ответа

Лучший ответ

Вы можете использовать {{X0} } со списком всех трех заглавных букв {{X1 }}

from itertools import combinations_with_replacement
upperletters = map(chr, range(65, 91))
print(np.random.choice(list(map(''.join, 
                                combinations_with_replacement(upperletters, 3))), 
                       size=8, replace=False))
#['JPZ' 'SSU' 'AQW' 'GKQ' 'AIZ' 'UYY' 'IJS' 'AOR']

Теперь, чтобы изменить данные, вы можете делать explode и map, используя словарь с эквивалентом.

s = df['sites'].explode()
codes = np.random.choice(list(map(''.join, 
                                  combinations_with_replacement(map(chr, range(65, 91)),
                                                                3))), 
                         size=s.nunique(), replace=False)
d = {word:code for word, code in zip(s.unique(), codes)}
print(d) #so in d you keep the correspondence
{'Elle': 'IVV', 'Harpers': 'DDW', 'Cosmo': 'DKM', 'Vogue': 'MRV'}

df['sites'] = s.map(d).groupby(level=0).agg(list)
print(df)
   row            sites
0    1  [IVV, DDW, DKM]
1    2       [IVV, MRV]
2    3            [DKM]
2
Ben.T 31 Авг 2020 в 22:33

Вот один из способов:

import pandas as pd
import random

# use sample data to create data frame
data = [(1, ["Elle", "Harpers", "Cosmo"]),
        (2, ["Elle", "Vogue"]),
        (3, ["Cosmo"])]
df = pd.DataFrame(data, columns=['row', 'sites'])

# get unique sites
unique_sites = df.explode('sites').loc[:, 'sites'].sort_values().unique()

# build map from actual site to masked site - could use full alphabet below
random.seed(123456)
site_to_scrambled = {
    site: ''.join(random.choices('ABCDEFGHI', k=4))
    for site in unique_sites }

def convert(sites, site_to_scrambled):
    return [site_to_scrambled[site] for site in sites]

# apply the conversion 
# (keep both sites and sites_scrambled to verify)
df['sites_scrambled'] = df['sites'].apply(
    lambda x: convert(x, site_to_scrambled))
print(df)

   row                   sites     sites_scrambled
0    1  [Elle, Harpers, Cosmo]  [AFAC, BCEB, HHAB]
1    2           [Elle, Vogue]        [AFAC, AIDF]
2    3                 [Cosmo]              [HHAB]
1
jsmart 31 Авг 2020 в 22:33