我有一个数据框,其中包含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.
解决方法:
实现这一目标的一种可能方法是:
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?).