基于值从多个列中的一个进行Pandas查找

kuuvgm7e  于 2023-05-15  发布在  其他
关注(0)|答案(7)|浏览(110)

我有以下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

因此,我希望通过使用列名找到基于另一行值的值。例如,第二个df中的值1990应该从第一个df中查找“a”,第二行应该从第一个df中查找“c”(=2)。
有什么想法吗

vwkv1x7d

vwkv1x7d1#

有一个内置的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
xt0899hw

xt0899hw2#

您创建了一个查找函数,并按行调用 Dataframe 上的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
ldfqzlk8

ldfqzlk83#

你可以使用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
wbgh16ku

wbgh16ku4#

使用按索引列标签查找值,因为DataFrame.lookup自1.2.0版起已弃用:

idx, cols = pd.factorize(df['best'])
df['value'] = df.reindex(cols, axis=1).to_numpy()[np.arange(len(df)), idx]
print (df)
   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
cyvaqqii

cyvaqqii5#

lookup自版本1.2.0起已弃用。使用melt,您可以将列“反透视”到行轴,其中列名默认存储在列variable中,其值存储在value中。query只返回列bestvariable相等的行。dropsort_values用于匹配您请求的格式。

df_new = (
    df.melt(id_vars=['Date', 'best'], value_vars=['a', 'b', 'c', 'd'])
    .query('best == variable')
    .drop('variable', axis=1)
    .sort_values('Date')
)

输出:

Date    best    value
0   1990    a       5
9   1991    c       2
14  1992    d       12
3   1993    a       5
flmtquvp

flmtquvp6#

一个使用Map器字典的简单解决方案:

vals = df[['a','b','c','d']].to_dict('list')
mapper = {k: vals[v][k] for k,v in zip(df.index, df['best'])}
df['value'] = df.index.map(mapper).to_numpy()

输出:

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
azpvetkf

azpvetkf7#

你可以像这样查找一个坐标列表

df = pd.DataFrame(index=['a', 'b', 'c'], columns=['x', 'y'], data=np.arange(0,6).reshape(3,2))

    x   y
a   0   1
b   2   3
c   4   5

coords = [('a', 'y'), ('b', 'x'), ('c', 'x')]
df.melt(var_name='column', ignore_index=False).set_index(['column'], append=True).loc[coords]

相关问题