我有一个包含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
。
答案 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 )