Получить новый столбец (согласование элемента в других) с пандами - PullRequest
3 голосов
/ 28 марта 2019

Мне нужна помощь с использованием фреймов данных панд. Вот кадр данных:

group   col1    col2    name
1       dog     40      canidae
1       dog     40      canidae
1       dog     40      canidae
1       dog     40      canidae
1       dog     40  
1       dog     40      canidae
1       dog     40      canidae
2       frog    85      dendrobatidae
2       frog    89      leptodactylidae
2       frog    89      leptodactylidae
2       frog    82      leptodactylidae
2       frog    89 
2       frog    81 
2       frog    89      dendrobatidae
3       horse   87      equidae1
3       donkey  76      equidae2
3       zebra   67      equidae3
4       bird    54      psittacidae
4       bird    56  
4       bird    34  
5       bear    67    
5       bear    54

То, что я хотел бы получить, это добавить столбец "consensus_name" и получить:

group col1   col2 name              consensus_name
1     dog    40   canidae           canidae
1     dog    40   canidae           canidae
1     dog    40                     canidae
1     dog    40   canidae           canidae
1     dog    40   canidae           canidae
2     frog   85   dendrobatidae     leptodactylidae
2     frog   89   leptodactylidae   leptodactylidae
2     frog   89   leptodactylidae   leptodactylidae
2     frog   82   leptodactylidae   leptodactylidae
2     frog   89                     leptodactylidae
2     frog   81                     leptodactylidae
2     frog   89   dendrobatidae     leptodactylidae
3     horse  87   equidae1          equidae3
3     donkey 76   equidae2          equidae3
3     zebra  67   equidae3          equidae3
4     bird   54   psittacidae       psittacidae
4     bird   56                     psittacidae
4     bird   34                     psittacidae
5     bear   67                     NA
5     bear   54                     NA

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

  • Для group1 есть 4 строки с именем 'canidae' и одна с пустым, поэтому для каждой я пишу 'canidae' в столбце consensus_name

  • Для group2 есть 2 строки с именем 'dendrobatidae', 2 с пустым и 3 строки с именем 'leptodactylidae', поэтому для каждого я пишу 'leptodactylidae' в столбце consensus_name .

  • Для group3 есть 3 строки с разными именами, поэтому, поскольку нет единого мнения, я получаю имя, которое является самым низким col2 числом, поэтому я пишу 'equidae3' в столбце consensus_name.

  • Для группы 4 информация имеется только в одной строке, поэтому это консенсус_имя group4, поэтому я пишу psittacidae в столбце consensus_name.

  • Для group5 информации нет, просто напишите NA в столбце consensus_name.

У кого-нибудь есть идеи сделать это с пандами? Спасибо за помощь:)


Выход для anky =

    group    col1  col2             name   consensus_name
0       1     dog    40          canidae          canidae
1       1     dog    40          canidae          canidae
2       1     dog    40          canidae          canidae
3       1     dog    40          canidae          canidae
4       1     dog    40              NaN          canidae
5       1     dog    40          canidae          canidae
6       1     dog    40          canidae          canidae
7       2    frog    85    dendrobatidae    dendrobatidae
8       2    frog    89  leptodactylidae  leptodactylidae
9       2    frog    89  leptodactylidae  leptodactylidae
10      2    frog    82  leptodactylidae  leptodactylidae
11      2    frog    89              NaN  leptodactylidae
12      2    frog    81              NaN  leptodactylidae
13      2    frog    89    dendrobatidae    dendrobatidae
14      3   horse    87         equidae1         equidae1
15      3  donkey    76         equidae2         equidae2
16      3   zebra    67         equidae3         equidae3
17      4    bird    54      psittacidae      psittacidae
18      4    bird    56              NaN      psittacidae
19      4    bird    34              NaN      psittacidae
20      5    bear    67              NaN              NaN
21      5    bear    54              NaN              NaN

Ответы [ 2 ]

4 голосов
/ 28 марта 2019

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

import numpy as np

def my_mode(gp):
    s = gp['name'].value_counts()
    s = s[s.eq(s.max())]

    if len(s) == 0:      # If all missing
        return np.NaN
    elif len(s) == 1:    # If there is a mode without ties
        return s.index[0]
    else:                # If ties, use the one with min col2 
        return gp.loc[gp['name'].isin(s.index)].sort_values('col2')['name'].iloc[0]

df['name'] = df['name'].replace({'': np.NaN})
df['consensus_name'] = df['group'].map(df.groupby('group').apply(my_mode))

Вывод:

    group    col1  col2             name   consensus_name
0       1     dog    40          canidae          canidae
1       1     dog    40          canidae          canidae
2       1     dog    40          canidae          canidae
3       1     dog    40          canidae          canidae
4       1     dog    40              NaN          canidae
5       1     dog    40          canidae          canidae
6       1     dog    40          canidae          canidae
7       2    frog    85    dendrobatidae  leptodactylidae
8       2    frog    89  leptodactylidae  leptodactylidae
9       2    frog    89  leptodactylidae  leptodactylidae
10      2    frog    82  leptodactylidae  leptodactylidae
11      2    frog    89              NaN  leptodactylidae
12      2    frog    81              NaN  leptodactylidae
13      2    frog    89    dendrobatidae  leptodactylidae
14      3   horse    87         equidae1         equidae3
15      3  donkey    76         equidae2         equidae3
16      3   zebra    67         equidae3         equidae3
17      4    bird    54      psittacidae      psittacidae
18      4    bird    56              NaN      psittacidae
19      4    bird    34              NaN      psittacidae
20      5    bear    67              NaN              NaN
21      5    bear    54              NaN              NaN   

Единственный крайний случай, который мы не определили явно, - это то, что происходит, когда есть связь для модальных значений и , которые они связывают для минимума col2.В настоящее время в этих ситуациях он выберет имя с самым низким индексом (которое появляется первым в DataFrame).

2 голосов
/ 28 марта 2019

Используйте pandas.DataFrame.Groupby.Series.transform и передайте ему функцию max:

#First fillna with empty string
df.name.fillna('', inplace=True)

df['consensus_name'] = df.groupby('group').name.transform('max')

print(df)
    group    col1  col2             name   consensus_name
0       1     dog    40          canidae          canidae
1       1     dog    40          canidae          canidae
2       1     dog    40          canidae          canidae
3       1     dog    40          canidae          canidae
4       1     dog    40                           canidae
5       1     dog    40          canidae          canidae
6       1     dog    40          canidae          canidae
7       2    frog    85    dendrobatidae  leptodactylidae
8       2    frog    89  leptodactylidae  leptodactylidae
9       2    frog    89  leptodactylidae  leptodactylidae
10      2    frog    82  leptodactylidae  leptodactylidae
11      2    frog    89                   leptodactylidae
12      2    frog    81                   leptodactylidae
13      2    frog    89    dendrobatidae  leptodactylidae
14      3   horse    87         equidae1         equidae3
15      3  donkey    76         equidae2         equidae3
16      3   zebra    67         equidae3         equidae3
17      4    bird    54      psittacidae      psittacidae
18      4    bird    56                       psittacidae
19      4    bird    34                       psittacidae
20      5    bear    67                                  
21      5    bear    54                                  

Редактировать после того, как указано, как правило, не применимо:

df['name'] = df.groupby('group').name.ffill()

df_group = df.groupby('group').name.apply(lambda x: pd.Series.mode(x, dropna=False)).reset_index()
df_group = df_group[df_group.level_1 == df_group.groupby('group').level_1.transform('max')]
df_group.rename({'name':'consensus_name'},axis=1, inplace=True)

df_final = pd.merge(df, df_group, on='group')

print(df_final)
    group    col1  col2             name  level_1   consensus_name
0       1     dog    40          canidae        0          canidae
1       1     dog    40          canidae        0          canidae
2       1     dog    40          canidae        0          canidae
3       1     dog    40          canidae        0          canidae
4       1     dog    40          canidae        0          canidae
5       1     dog    40          canidae        0          canidae
6       1     dog    40          canidae        0          canidae
7       2    frog    85    dendrobatidae        0  leptodactylidae
8       2    frog    89  leptodactylidae        0  leptodactylidae
9       2    frog    89  leptodactylidae        0  leptodactylidae
10      2    frog    82  leptodactylidae        0  leptodactylidae
11      2    frog    89  leptodactylidae        0  leptodactylidae
12      2    frog    81  leptodactylidae        0  leptodactylidae
13      2    frog    89    dendrobatidae        0  leptodactylidae
14      3   horse    87         equidae1        2         equidae3
15      3  donkey    76         equidae2        2         equidae3
16      3   zebra    67         equidae3        2         equidae3
17      4    bird    54      psittacidae        0      psittacidae
18      4    bird    56      psittacidae        0      psittacidae
19      4    bird    34      psittacidae        0      psittacidae
20      5    bear    67              NaN        0              NaN
21      5    bear    54              NaN        0              NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...