2017-09-22 68 views
1

我需要使用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 

可以很容易地查找并获得系列作为输出:

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

1 Salem 
Name: capital, dtype: object 

,但我想获得字符串'塞勒姆:

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

'Salem' 

.values[0]似乎有点笨重......有没有更好的方法? (FWIW:我的真实数据最多可能有50行,但是很多列,所以如果我设置了索引列,无论选择哪个列,都会有这样的查找操作,这不是基于一个索引,而较少行的意思是我不介意这是O(n)的查找)

+1

你可以在那里查看答案https://stackoverflow.com/questions/46352688/accessing-arrays-stored-in-pandas-dataframe#comment79665647_46352688 – Wen

回答

1

是的,你可以使用Series.item如果查找总是从Series返回一个元素:

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 
+0

哦好 - 由于某种原因,每当我通过熊猫文档洞察那里这是我不知道的一点隐藏的方面。谢谢! https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.item.html#pandas.Series.item –

+0

为什么'.loc' btw?好点吗? –

+0

是的,如果数据量较大,'loc'会更快。 – jezrael

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的语法是简单的和字典。这可能是足够建立state_capitals的理由。