Декодировать один горячий кадр в Pandas - PullRequest
0 голосов
/ 31 октября 2018

У меня есть 2 кадра с данными, как показано ниже:

df1:
====
id   name   age   likes
---  -----  ----  -----
0     A      21    rose
1     B      22    apple
2     C      30    grapes
4     D      21    lily

df2:
====
category    Fruit   Flower 
---------  -------  -------
orange      1        0
apple       1        0       
rose        0        1
lily        0        1
grapes      1        0

То, что я пытаюсь сделать, это добавить еще один столбец в df1, который будет содержать слово «Fruit» или «Flower» в зависимости от однократного кодирования в df2 для этой записи. Я ищу чисто панд / numpy реализацию.

Любая помощь будет оценена.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 31 октября 2018

IIUC, вы можете использовать .apply и установить axis = 1 или axis = "columns", что означает применение функции к каждой строке.

df3 = df1.merge(df2, left_on='likes', right_on='category')

# you can add your one hot columns in here.
categories_col = ['Fruit','Flower']

def get_category(x):
    for category in categories_col:
        if x[category] == 1:
            return category
df1["new"] = df3.apply(get_category, axis=1)

print(df1)
    id  name    age likes   new
0   0   A   21  rose    Flower
1   1   B   22  apple   Fruit
2   2   C   30  grapes  Fruit  
3   4   D   21  lily    Flower

Но убедитесь, что ваш фрейм данных category_col должен быть одним горячим кодированием.

0 голосов
/ 31 октября 2018

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

вот рабочий пример:

df1 = pd.DataFrame([['orange',12],['rose',3],['apple',44],['grapes',1]], columns = ['name', 'age'])


df1
    name    age
0   orange  12
1   rose    3
2   apple   44
3   grapes  1
df2 = pd.DataFrame([['orange',1],['rose',0],['apple',1],['grapes',1],['daffodils',0],['berries',1]], columns = ['cat', 'Fruit'])

df2
    cat         Fruit
0   orange      1
1   rose        0
2   apple       1
3   grapes      1
4   daffodils   0
5   berries     1

одной строкой, запустите listcomp с условным оператором и выполните объединенные df1 и df2 на лету, где ключ df1.name = df2.cat:

df1['flag'] = ['Fruit' if i == 1 else 'Flower' for i in df1.merge(df2,how='left',left_on='name', right_on='cat').Fruit]
df1
выход
name    age     flag
0   orange  12  Fruit
1   rose    3   Flower
2   apple   44  Fruit
3   grapes  1   Fruit
0 голосов
/ 31 октября 2018

Вы можете использовать apply() для этого:

df1['type_string'] = df2.apply(lambda x: 'Fruit' if x.Fruit else 'Flower', 1)  

Вот пример:

import pandas as pd
from io import StringIO

df1 = pd.read_csv(StringIO(
"""
0     A      21    rose
1     B      22    apple
2     C      30    grapes
4     D      21    lily
"""), sep='\s+', header=None)

df2 = pd.read_csv(StringIO(
"""
orange      1        0
apple       1        0       
rose        0        1
lily        0        1
grapes      1        0
"""), sep='\s+', header=None)

df1.columns = ['id', 'name', 'age', 'likes']
df2.columns = ['category', 'Fruit', 'Flower']

df1['category'] = df2.apply(lambda x: 'Fruit' if x.Fruit else 'Flower', 1)

Input

   id name  age   likes
0   0    A   21    rose
1   1    B   22   apple
2   2    C   30  grapes
3   4    D   21    lily

Выход

   id name  age   likes category
0   0    A   21    rose    Fruit
1   1    B   22   apple    Fruit
2   2    C   30  grapes   Flower
3   4    D   21    lily   Flower
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...