от R до Python: создайте ряд идентификаторов ключей по порядку на дубликатах - PullRequest
0 голосов
/ 16 сентября 2018

Я хочу создать ключ идентификатора для серии в строке, которая повторяется в одном столбце.Первые десять строк должны быть идентификатором № 1, следующие десять № 2 и так далее.В R это просто, и я получаю ожидаемый результат с помощью dplyr.

R:

library(tidyverse)

question = c('q1', 'q2', 'q3', 'q4', 'q5', 'q1', 'q2', 'q3', 'q4', 'q5', 'q1', 'q2', 'q3', 'q4', 'q5')
answer <- c('a1', 'a2', 'a3', 'a4', 'a5', 'a1', 'a2', 'a3', 'a4', 'a5', 'a1', 'a2', 'a3', 'a4', 'a5')

df <- data_frame(question, answer)

# A tibble: 15 x 2
   question answer
   <chr>    <chr> 
 1 q1       a1    
 2 q2       a2    
 3 q3       a3    
 4 q4       a4    
 5 q5       a5    
 6 q1       a1    
 7 q2       a2    
 8 q3       a3    
 9 q4       a4    
10 q5       a5    
11 q1       a1    
12 q2       a2    
13 q3       a3    
14 q4       a4    
15 q5       a5 

Если мы запустим только group_by и mutate, чтобы добавитьключ к серии мы получаем то, что я хочу:

df2 <- df %>% 
  group_by(question) %>% 
  mutate(id = row_number())

# A tibble: 15 x 3
# Groups:   question [5]
   question answer    id
   <chr>    <chr>  <int>
 1 q1       a1         1
 2 q2       a2         1
 3 q3       a3         1
 4 q4       a4         1
 5 q5       a5         1
 6 q1       a1         2
 7 q2       a2         2
 8 q3       a3         2
 9 q4       a4         2
10 q5       a5         2

И я заканчиваю с:

df2 <- df %>% 
  group_by(question) %>% 
  mutate(id = row_number()) %>% 
  spread(question, answer) 

# final table:
# A tibble: 3 x 6
      id    q1    q2    q3    q4    q5   
      <int> <chr> <chr> <chr> <chr> <chr>
    1     1 a1    a2    a3    a4    a5   
    2     2 a1    a2    a3    a4    a5   
    3     3 a1    a2    a3    a4    a5 

Python:

Теперь яне могу понять, как получить такой же результат в пандах.Я попытался сгруппировать и объединить, но не повезло.

import pandas as pd

data = {'question': ['question one', 'question two', 
                 'question three', 'question four', 
                 'question five', 'question one', 
                 'question two', 'question three', 
                 'question four', 'question five', 
                 'question one', 'question two', 
                 'question three', 'question four', 'question five'], 
    'answer':['answer one', 'answer two', 'answer three', 
              'answer four', 'answer five', 'answer one', 
              'answer two', 'answer three', 'answer four', 
              'answer five', 'answer one', 'answer two', 
              'answer three', 'answer four', 'answer five']}

df = pd.DataFrame(data)

Используя merge и rest_index (), он переупорядочивает строки и назначает идентификатор для нового заказа, а это не то, что я хочу:

df2 = df.merge(df.drop_duplicates('question').reset_index(), on='question')

          question      answer_x  index      answer_y
0     question one    answer one      0    answer one
1     question one    answer one      0    answer one
2     question one    answer one      0    answer one
3     question two    answer two      1    answer two
4     question two    answer two      1    answer two
5     question two    answer two      1    answer two

Используя groupby, я получаю беспорядок, который тоже не тот, который я хочу:

df['id'] = df.groupby('question').ngroup()

          question        answer  id
0     question one    answer one   2
1     question two    answer two   4
2   question three  answer three   3
3    question four   answer four   1
4    question five   answer five   0
5     question one    answer one   2
6     question two    answer two   4
7   question three  answer three   3
8    question four   answer four   1
9    question five   answer five   0

Как получить тот же вывод, что и с dplyr?Изменить: Чтобы добавить больше деталей, мне нужно, чтобы вывод был таким, как дает мне dplyr, так как это часть автоматизированной системы.

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

ngroup - это число из группы, а не число внутри группы.Как объясняют документы , дополнение к этому дается как cumcount.

Примерно, вы можете использовать assign для mutate, groupby/cumcount для row_number иpivot для вашего spread:

In [306]: df.assign(id=df.groupby("question").cumcount()).pivot("id", "question", "answer")
Out[306]: 
question  q1  q2  q3  q4  q5
id                          
0         a1  a2  a3  a4  a5
1         a1  a2  a3  a4  a5

и добавьте reset_index(), если вы хотите, чтобы id был столбцом.

К сожалению, я думаю, что действительно соответствуетОжидаемый результат, мы должны были бы гарантировать заказ.На github есть несколько открытых билетов о том, что автоматическая сортировка неудобна, но мы можем сделать это вручную.Вернемся к английскому тексту:

In [327]: d2 = df.assign(id=df.groupby("question").cumcount()).pivot("id", "question", "answer")

In [328]: d2.reindex(df.question.drop_duplicates(), axis=1)
Out[328]: 
question question one question two question three question four question five
id                                                                           
0          answer one   answer two   answer three   answer four   answer five
1          answer one   answer two   answer three   answer four   answer five
0 голосов
/ 16 сентября 2018

Я знаю, что вопрос о dplyr, однако я предлагаю свою альтернативу, используя data.table и reshape2.

library(data.table)
library(reshape2)
setDT(df)[,new := (1:.N), by = question]
dcast(df, new ~ question, value.var = "answer")

   new q1 q2 q3 q4 q5
1:   1 a1 a2 a3 a4 a5
2:   2 a1 a2 a3 a4 a5
3:   3 a1 a2 a3 a4 a5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...