Pandas поиск по значению

У меня есть следующий DataFrame:

Date    best    a    b    c    d
1990    a       5    4    7    2
1991    c       10   1    2    0
1992    d       2    1    4    12
1993    a       5    8    11   6

Я хотел бы сделать dataframe следующим образом:

Date    best    value   
1990    a       5
1991    c       2
1992    d       12
1993    a       5

Итак, я ищу, чтобы найти значение на основе другого значения строки, используя имена столбцов. Например, значение для 1990 во втором df должно искать "a" из первого df, а вторая строка должна искать "c" (= 2) из ​​первого df.

Любые идеи?

Ответ 1

Существует встроенная функция lookup, которая может обрабатывать подобные ситуации (поиск по строке/столбцу). Я не знаю, насколько это оптимизировано, но может быть быстрее, чем применяемое решение.

In [9]: df['value'] = df.lookup(df.index, df['best'])

In [10]: df
Out[10]: 
   Date best   a  b   c   d  value
0  1990    a   5  4   7   2      5
1  1991    c  10  1   2   0      2
2  1992    d   2  1   4  12     12
3  1993    a   5  8  11   6      5

Ответ 2

Вы создаете функцию поиска и вызываете apply в строке данных по строке, это не очень эффективно для больших dfs, хотя

In [245]:

def lookup(x):
    return x[x.best]
df['value'] = df.apply(lambda row: lookup(row), axis=1)
df
Out[245]:
   Date best   a  b   c   d  value
0  1990    a   5  4   7   2      5
1  1991    c  10  1   2   0      2
2  1992    d   2  1   4  12     12
3  1993    a   5  8  11   6      5

Ответ 3

Вы можете сделать это, используя np.where, как показано ниже. Я думаю, что это будет более эффективным

import numpy as np
import pandas as pd

df = pd.DataFrame([['1990', 'a', 5, 4, 7, 2], ['1991', 'c', 10, 1, 2, 0], ['1992', 'd', 2, 1, 4, 12], ['1993', 'a', 5, 8, 11, 6]], columns=('Date', 'best', 'a', 'b', 'c', 'd'))
arr = df.best.values

cols = df.columns[2:]
for col in cols:
    arr2 = df[col].values
    arr = np.where(arr==col, arr2, arr)

df.drop(columns=cols, inplace=True)
df["values"] = arr
df

Результат

Date    best    values
0   1990    a   5
1   1991    c   2
2   1992    d   12
3   1993    a   5