Python 将URL参数解析为单独的列

Python 将URL参数解析为单独的列,python,pandas,Python,Pandas,我有一个带有URL列的dataframe,如果URL中存在指定参数的值,我希望将其解析为带有行的新列。我正在使用一个函数,该函数循环遍历dataframe列中的每一行并解析指定的URL参数,但是当我在函数完成后尝试选择该列时,我得到了一个keyError。我应该以不同的方式设置此新列的值吗?有没有比循环表中的值并运行此过程更有效的方法 错误: KeyError: 'utm_source' url示例(df['landing\u page\u url']): 代码: 而不是 try: re

我有一个带有URL列的dataframe,如果URL中存在指定参数的值,我希望将其解析为带有行的新列。我正在使用一个函数,该函数循环遍历dataframe列中的每一行并解析指定的URL参数,但是当我在函数完成后尝试选择该列时,我得到了一个keyError。我应该以不同的方式设置此新列的值吗?有没有比循环表中的值并运行此过程更有效的方法

错误:

KeyError: 'utm_source'
url示例(
df['landing\u page\u url']
):

代码:

而不是

try:
   return parse_qs(urlparse(url).query)[field][0]
except KeyError:
   return ''
您只需执行以下操作:

return parse_qs(urlparse(url).query).get(field, [''])[0]
这里的技巧是
mydict.get(key,default)
而不是
mydict[key]
。如果密钥不存在,将返回默认值

有没有比循环表中的值并运行此过程更有效的方法

不是真的。通过每个url的循环必须以任何一种方式完成。但是现在,您正在覆盖每个url的数据帧。这意味着,如果两个不同的URL在查询中具有不同的源,则列表中的最后一个URL将获胜。我不知道这是否是故意的

另请注意:此行

df['utm_source'] == get_query_field(i, 'utm_source')
实际上什么都没做
=
是一个比较运算符,“左侧是否匹配右侧”。您可能想使用
=
df.append({'utm\u source':get\u query\u field(..)})

而不是

try:
   return parse_qs(urlparse(url).query)[field][0]
except KeyError:
   return ''
您只需执行以下操作:

return parse_qs(urlparse(url).query).get(field, [''])[0]
这里的技巧是
mydict.get(key,default)
而不是
mydict[key]
。如果密钥不存在,将返回默认值

有没有比循环表中的值并运行此过程更有效的方法

不完全是。每个url的循环都必须以任何方式完成。不过,现在,您正在覆盖每个url的数据框架。这意味着,如果两个不同的url在查询中有不同的源,列表中的最后一个将获胜。我不知道这是否是有意的

另请注意:此行

df['utm_source'] == get_query_field(i, 'utm_source')

实际上并没有做任何事情。
=
是一个比较运算符,“左侧是否匹配右侧”。您可能打算使用
=
df.append({'utm_source':get_query_field(..)})

我认为您的for循环不起作用。看起来每次它都会覆盖您试图设置的整个列。我想用我的方法测试速度,但我几乎可以肯定这将比迭代更快

#Simplify the function here as recommended by Nick
def get_query_field(url, field):
    if isinstance(url, str):
        return parse_qs(urlparse(url).query).get(field, [''])[0]
    return ''

#Use apply to create new columns based on the url
df['utm_source'] = df['landing_page_url'].apply(get_query_field, args=['utm_source'])
df['utm_campaign'] = df['landing_page_url'].apply(get_query_field, args=['utm_campaign'])
df['utm_term'] = df['landing_page_url'].apply(get_query_field, args=['utm_term'])

我认为你的for循环行不通。看起来每次它都会覆盖您试图设置的整个列。我想用我的方法测试速度,但我几乎可以肯定这将比迭代更快

#Simplify the function here as recommended by Nick
def get_query_field(url, field):
    if isinstance(url, str):
        return parse_qs(urlparse(url).query).get(field, [''])[0]
    return ''

#Use apply to create new columns based on the url
df['utm_source'] = df['landing_page_url'].apply(get_query_field, args=['utm_source'])
df['utm_campaign'] = df['landing_page_url'].apply(get_query_field, args=['utm_campaign'])
df['utm_term'] = df['landing_page_url'].apply(get_query_field, args=['utm_term'])

嘿,尼克,谢谢你的捷径!至于你关于压倒一切的问题,这不是故意的。我想将解析后的参数值作为行按正确的索引顺序添加到各自的列中。我应该使用
.append()
方法而不是我正在做的事情吗?嗯,我在尝试
.append(…)
类型错误:无法连接类型为“”的对象时收到错误;只有Series和DataFrame OBJ是有效的
,将其设置为单个=(很好的捕获),会在执行时用最后一个值覆盖它mentioned@cphill尝试使用以下语法:
df.append({'utm\u source':get\u query\u field(..)}
嘿,尼克,谢谢你的快捷方式!至于你关于压倒一切的问题,这不是故意的。我想将解析后的参数值作为行按正确的索引顺序添加到各自的列中。我应该使用
.append()
方法而不是我正在做的事情吗?嗯,我在尝试
.append(…)
类型错误:无法连接类型为“”的对象时收到错误;只有Series和DataFrame OBJ是有效的
,将其设置为单个=(很好的捕获),会在执行时用最后一个值覆盖它mentioned@cphill尝试使用以下语法:
df.append({'utm\u source':get\u query\u field(..)}
谢谢您的回答。非常快的方法,很高兴了解
.apply()
方法!谢谢你的回答。非常快的方法,很高兴了解
.apply()
方法!