Категоризация строк в зависимости от размера группы - PullRequest
0 голосов
/ 02 апреля 2020

В целях контекста представьте себе форум inte rnet с темами и сообщениями. Каждая тема и каждое сообщение имеют свой уникальный идентификатор. Кроме того, несколько сообщений могут быть связаны с темой (можно также представить людей (= сообщения) и семейства (= темы), к которым они принадлежат):

У меня есть кадр данных в pandas с двумя столбцами : thread_id и post_id. Каждая строка в моем датафрейме - это пост на этом форуме. thread_id показывает, к какой теме принадлежит сообщение, а post_id показывает уникальный идентификатор сообщения.

Теперь я хочу добавить третий столбец: thread_size. Показывает, к какой теме принадлежит сообщение. Этот столбец имеет одно из трех различных значений: small, medium или big. Значение выбирается в зависимости от, как вы уже догадались, размера потока. Существует два порога (верхний и нижний), по которым измеряется размер потока.

Я попытался сгруппировать сообщения по темам, а затем установить размер thread_size, используя a для l oop, и если, elif, еще заявления. Но это не похоже на работу:

forum["thread_size"] = np.nan

for thread_id, frame in forum.groupby(["thread_id"]):
    post_count = frame.size
    if post_count > 400:
        frame["thread_size"] = "big"
    elif post_count > 300:
        frame["thread_size"] = "medium"
    else:
        frame["thread_size"] = "small"

РЕДАКТИРОВАТЬ: Думайте о forum как о городе (информационном кадре) с людьми, принадлежащими к семьям. Каждая строка в моем фрейме данных представляет человека (сообщение), принадлежащего семье (поток). Я хочу расширить city-dataframe с помощью столбца с именем family-size. Таким образом, у каждого человека (строки) теперь есть информация, к какой семье он принадлежит, и принадлежат ли они к семье big, medium или small: До:

[name]    [family]   
 oscar     potter       
 frederic  minamisawa  
 blerim    meier       
 marina    minamisawa   

После:

[name]    [family]     [family-size]
 oscar     potter       small
 frederic  minamisawa   big
 blerim    meier        medium
 marina    minamisawa   big

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

Используйте pd.cut, чтобы положить их в урны. Сначала немного фиктивных данных:

n = 1000
np.random.seed(2)

# I want to bias the threads such that thread 1 has a decent chance
# of being "large", 2 is "medium" and 3 and 4 are "small"
thread_id = np.random.choice([1,2,3,4], size=n, p=[0.4, 0.3, 0.2, 0.1])

# post_id is unique, may as well be sequential
post_id = np.arange(n)

# The dataframe
forum = pd.DataFrame({
    'thread_id': thread_id,
    'post_id': post_id
})

Теперь к вашей проблеме:

stat = forum.groupby('thread_id').size().to_frame('count')
stat['size'] = pd.cut(stat['count'], [0, 300, 400, np.inf], labels=['small', 'medium', 'large'])

Функция pd.cut разрезает серию stat['count'] на 3 корзины:

  • (0 - 300]: маленький
  • (300 - 400]: средний
  • (400 - инф.): Большой

Результат:

           count    size
thread_id               
1            416   large
2            313  medium
3            165   small
4            106   small
0 голосов
/ 03 апреля 2020

Нашел то, что хотел:

thread_category = lambda x: 2 if x > 400 else (1 if x > 300 else 0)

forum["thread_size"] = forum.groupby('thread_id')["post_id"].transform(lambda x: thread_category(len(x)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...