вернуть разные значения из разных столбцов в соответствии с условиями pandas - PullRequest
0 голосов
/ 13 апреля 2020

снимок DF выглядит так:

dataframe

idf=pd.DataFrame({'p1': {549: 'Staffordshire_bullterrier', 1374: 'kelpie', 641: 'Samoyed'},
 'p1_conf': {549: 0.6892590000000001, 1374: 0.519047, 641: 0.362596},
 'p1_dog': {549: True, 1374: True, 641: True},
 'p2': {549: 'Norwegian_elkhound', 1374: 'German_shepherd', 641: 'Eskimo_dog'},
 'p2_conf': {549: 0.026121, 1374: 0.296069, 641: 0.245395},
 'p2_dog': {549: True, 1374: True, 641: True},
 'p3': {549: 'American_Staffordshire_terrier',
  1374: 'dingo',
  641: 'Siberian_husky'},
 'p3_conf': {549: 0.0230747, 1374: 0.0610053, 641: 0.108232},
 'p3_dog': {549: True, 1374: False, 641: True},
 'breed': {549: 'Staffordshire_bullterrier', 1374: 'kelpie', 641: 'Samoyed'}})

Моя цель - вернуть наиболее доверчивую породу. например: если p1_dog имеет значение true, то p1 должен быть возвращен. если нет, вторым наиболее уверенным является p2_dog, тогда должен быть возвращен p2 и т. д. c. конечно, я могу написать что-то вроде этого:

idf['breed']=idf.query("p1_dog==1").p1
idf['breed']=idf['breed'].fillna(idf.query("p1_dog==0 and p2_dog==1").p2)
idf['breed']=idf['breed'].fillna(idf.query("p1_dog==0 and p2_dog==0 and p3_dog==1").p3)

ожидаемый результат - последний столбец «породы», который мой код выше может служить цели. но я думаю, что это повторяется, а не dry. Что делать, если у меня есть сотни прогнозов? каково лучшее решение этого? вперед, спасибо!

Ответы [ 2 ]

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

Мне кажется, это идеальный случай для np.select

np.select

import pandas as pd
import numpy as np

condlist = [df["p1_dog"]==1,
            ((df["p1_dog"]==0) & (df["p2_dog"]==1)),
            ((df["p1_dog"]==0) & (df["p2_dog"]==0) & (df["p3_dog"]==1))]

choicelist = [df["p1"], df["p2"], df["p3"]]

df["breed"] = np.select(condlist, choicelist)

Обновление: обобщение

Есть немного более обобщенный c Решение, в частности, когда у вас есть много столбцов для сравнения. Он использует np.argmax, и это решение

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {"p1":['Staffordshire_bullterrier', 'Samoyed', 'kelpie','dingo'],
     "p1_dog":[True, False, False, True],
     "p2": ['Norwegian_elkhound', 'Eskimo_dog', 'German_shepherd', 'kelpie'],
     "p2_dog":[False, True, False, True],
     "p3":['American_Staffordshire_terrier', 'Siberian_husky', 'dingo','Samoyed'],
     "p3_dog":[False, True, True, True]
     })

Сначала мы выбираем первое истинное значение в каждой строке

sel = df[["p1_dog", "p2_dog", "p3_dog"]].values.argmax(1)

Затем мы извлекаем матрицу с породой имена

mat = df[["p1", "p2", "p3"]].values

И мы наконец определим породу, используя ваши логики c

df["breed"] = mat[np.arange(mat.shape[0]), sel]
0 голосов
/ 22 апреля 2020

Для каждой строки в кадре данных найдите имя столбца с максимальным значением

x = idf[['p1_conf','p2_conf','p3_conf']].idxmax(axis=1) 

Получить номер столбца перед именем столбца из x

breed_col = [idf.columns.get_loc(x.iloc[i])-1 for i in range(0, 3)] 

Извлечь значение ячейки, соответствующее строка и столбец: i и breed_col [i]

breed2 = []
for i in range(0,3):
    breed2.append(idf.iloc[i,breed_col[i]]) 

breed2_df = pd.DataFrame(breed2, columns = ['breed2'])

Сброс индексов для включения конкатенации кадров данных

idf.reset_index(drop=True, inplace=True) 
pd.concat([idf, breed2_df], axis=1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...