查找Pandas数据帧中的第一个匹配项

时间:2017-09-22 18:48:25

标签: python pandas dataframe

我需要在不属于索引的列上使用DataFrame作为查找表。例如(这只是一个简单的说明):

import pandas as pd

westcoast = pd.DataFrame([['Washington','Olympia'],['Oregon','Salem'],
                          ['California','Sacramento']],
                        columns=['state','capital'])
print westcoast

        state     capital
0  Washington     Olympia
1      Oregon       Salem
2  California  Sacramento

查找并将Series作为输出很容易:

westcoast[westcoast.state=='Oregon'].capital

1    Salem
Name: capital, dtype: object

但我想获得字符串'Salem':

westcoast[westcoast.state=='Oregon'].capital.values[0]

'Salem'

并且.values[0]似乎有点笨拙......有更好的方法吗?

(FWIW:我的真实数据最多可能包含50行,但列数很多,所以如果我设置了一个索引列,无论我选择哪一列,都会有这样的查找操作,而不是基于一个索引,行数相对较少意味着我不在乎它是否是O(n)查找。)

2 个答案:

答案 0 :(得分:2)

是的,如果查询总是返回Series中的一个元素,则可以使用Series.item

westcoast.loc[westcoast.state=='Oregon', 'capital'].item()

如果查找没有返回任何内容,或者一个或多个值,并且您只需要第一个项目,则可以处理异常:

s = westcoast.loc[westcoast.state=='Oregon', 'capital']
s = np.nan if s.empty else s.iat[0] 
print (s) #Salem

s = westcoast.loc[westcoast.state=='New York', 'capital']
s = np.nan if s.empty else s.iat[0] 
print (s)
nan

处理异常的更通用的解决方案,因为有3种可能的输出方案:

westcoast = pd.DataFrame([['Washington','Olympia'],['Oregon','Salem'],
                          ['California','Sacramento'],['Oregon','Portland']],
                        columns=['state','capital'])

print (westcoast)
        state     capital
0  Washington     Olympia
1      Oregon       Salem
2  California  Sacramento
3      Oregon    Portland

s = westcoast.loc[westcoast.state=='Oregon', 'capital']

#if not value returned
if s.empty:
    s = 'no match'

#if only one value returned
elif len(s) == 1:
    s = s.item()
else:

# if multiple values returned, return a list of values
    s = s.tolist()

print (s)
['Salem', 'Portland']

可以创建查找功能:

def look_up(a):
    s = westcoast.loc[westcoast.state==a, 'capital']
    #for no match
    if s.empty:
        return np.nan
    #for match only one value
    elif len(s) == 1:
        return s.item()
    else:
    #for return multiple values
        return s.tolist()

print (look_up('Oregon'))
['Salem', 'Portland']

print (look_up('California'))
Sacramento

print (look_up('New Yourk'))
nan

答案 1 :(得分:1)

如果您要频繁查找此类,那么将state作为索引是值得的:

state_capitals = westcoast.set_index('state')['capital']
print(state_capitals['Oregon'])
# Salem

使用索引时,每次查找平均为O(1),而westcoast['state']=='Oregon'则需要O(n)次比较。当然,构建索引也是O(n),因此您需要进行许多查找才能获得回报。

同时,一旦你state_capitals语法很简单,就像dict一样。这可能足以构建state_capitals