Python Pandas:通过搜索子字符串查找表

时间:2015-09-02 07:01:10

标签: python python-2.7 pandas lookup string-search

我有一个包含app user-agents列的数据框。我需要做的是从这个专栏中识别特定的应用程序。例如,

NewWordsWithFriendsFree/2.3 CFNetwork/672.1.15 Darwin/14.0.0将归入Words With Friends

iPhone3,1; iPhone OS 7.1.2; com.fingerarts.sudoku2; 143441-1,24 will be Sudoku by FingerArts etc.

我将有另一个数据帧,其中包含我需要匹配的字符串。例如,

Keyword                 Game 
NewWordsWithFriends     Words With Friends
com.fingerarts.sudoku   Sudoku by FingerArts

如何为pandas数据框执行此类查找?例如,数据框就像

user    date                 user-agent
 A      2015-09-02 13:45:56  NewWordsWithFriendsFree/2.3 CFNetwork/672.1.15 Darwin/14.0.0
 B      2015-08-31 23:04:21  iPhone3,1; iPhone OS 7.1.2; com.fingerarts.sudoku2; 143441-1,24

查找后我想要一个新列GameName

2 个答案:

答案 0 :(得分:1)

实现这一目标的一种可能方法是:

import pandas as pd                                                              

# some example data
qry = pd.DataFrame.from_dict({"Keyword": ["NewWordsWithFriends",                 
                                          "com.fingerarts.sudoku"],              
                              "Game": ["Words With Friends",                     
                                       "Sudoku by FingerArts"]})                 

df = pd.DataFrame.from_dict({"user-agent" : ["NewWordsWithFriendsFree/2.3 CFNetwork/672.1.15 Darwin/14.0.0",     
                                             "iPhone3,1; iPhone OS 7.1.2; com.fingerarts.sudoku2; 143441-1,24"]})

keywords = qry.Keyword.tolist()                                                  
games = qry.Game.tolist()                                                        

def select(x):                                                                   
    for key, game in zip(keywords, games):                                       
        if key in x:                                                             
            return game                                                          

df["GameName"] = df["user-agent"].apply(select)  

这将给出:

In [41]: df
Out[41]: 
                                          user-agent              GameName
0  NewWordsWithFriendsFree/2.3 CFNetwork/672.1.15...    Words With Friends
1  iPhone3,1; iPhone OS 7.1.2; com.fingerarts.sud...  Sudoku by FingerArts

如果您需要对大型数据集执行此操作,则需要测试此解决方案的性能,并查看它是否足够快以达到您的目的。

如果没有,可能会优化测试字符串的方式:

为所有可能的游戏设置一个外循环,然后使用.apply返回每列游戏的结果可以加快速度,因为它可以避免每次调用select()等所有游戏的循环

确定您可以使用的瓶颈line_profiler(请参阅How can I profile python code line-by-line?)。

答案 1 :(得分:1)

df = pd.DataFrame({'date' : ['2015-09-02 13:45:56' , '2015-08-31 23:04:21'] , 'user-agent' : ['NewWordsWithFriendsFree/2.3 CFNetwork/672.1.15 Darwin/14.0.0' , 'iPhone3,1; iPhone OS 7.1.2; com.fingerarts.sudoku2; 143441-1,24']  })

map_df = pd.DataFrame({'Keyword' :  ['NewWordsWithFriends' , 'com.fingerarts.sudoku'], 'Game' : [ 'Words With Friends', 'Sudoku by FingerArts'] })

mapping = {vals[1] : vals[0] for vals in  map_df.values}


regex = '|'.join([keyword.replace('.' , '\.') for keyword in map_df['Keyword']])

def get_keyword(user_agent):
    matches = re.findall(regex ,user_agent)
    return matches[0] if len(matches) > 0 else np.nan


df['GameName'] = df['user-agent'].apply(get_keyword)

df['GameName'] = df['GameName'].map(mapping)

get_keyword函数的另一个实现可能是

def get_keyword(user_agent):
    for keyword in map_df['Keyword']:
        if keyword in user_agent:
            return keyword

获取映射的另一种方法是创建series

mapping = pd.Series(map_df['Game'].values , index = map_df.Keyword )