Как организовать многопоточное выполнение большого количества вызовов выбора панд данных для большого набора данных - PullRequest
0 голосов
/ 05 мая 2018

df - это кадр данных, содержащий 12 миллионов + несортированных строк. Каждая строка имеет идентификатор группы.

Конечная цель состоит в том, чтобы случайным образом выбрать 1 строку для каждого уникального идентификатора группы, таким образом заполняя новый столбец с именем SELECTED, где 1 означает выбранное 0 означает противоположное

Может быть более 5000 уникальных идентификаторов группы. Ищете лучшее и более быстрое решение, чем следующее, Потенциально многопоточное решение?

for sec in df['GROUP'].unique():
    sz = df.loc[df.GROUP == sec, ['SELECTED']].size
    sel = [0]*sz
    sel[random.randint(0,sz-1)] = 1
    df.loc[df.GROUP == sec, ['SELECTED']] = sel

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Вы можете попробовать векторизованную версию, которая, вероятно, ускорит процесс, если у вас много классов.

import pandas as pd

# get fake data
df = pd.DataFrame(pd.np.random.rand(10))
df['GROUP'] = df[0].astype(str).str[2]

# mark one element of each group as selected
df['selected'] = df.index.isin(    # Is current index in a selected list?
        df.groupby('GROUP')        # Get a GroupBy object.
        .apply(pd.Series.sample)   # Select one row from each group.
        .index.levels[1]           # Access index - in this case (group, old_id) pair; select the old_id out of the two.
        ).astype(pd.np.int) # Convert to ints.

Обратите внимание, что это может не сработать, если присутствуют повторяющиеся индексы.

0 голосов
/ 05 мая 2018

Я не знаю фрейм данных panda, но если вы просто установите selected, где он должен быть один, и позже предположите, что отсутствие атрибута означает not selected, вы можете избежать обновления всех элементов.

Вы также можете сделать что-то вроде этого:

selected = []
for sec in df['GROUP'].unique():
    selected.append(random.choice(sec))

или со списком

selected = [random.choice(sec) for sec in  df['GROUP'].unique()]

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

Если вы действительно хотите многопоточность, взгляните на concurrent.futures https://docs.python.org/3/library/concurrent.futures.html

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