Python 在数据帧中将列表转换为集合

Python 在数据帧中将列表转换为集合,python,pandas,set,Python,Pandas,Set,我想在dataframe列的每一行中搜索子字符串。我在某个地方读到,如果可以将列转换为一个集合,则搜索速度更快。我尝试使用此处建议的方法: 但我得到了一些意想不到的结果。我的数据框如下所示: R_id Badges 0 7LBCS New Reviewer - 1 Review 1 8FKME New Reviewer - 1 Review; New Photographer - 1 Photo; Reviewer - 3 Rev

我想在dataframe列的每一行中搜索子字符串。我在某个地方读到,如果可以将列转换为一个集合,则搜索速度更快。我尝试使用此处建议的方法: 但我得到了一些意想不到的结果。我的数据框如下所示:

      R_id        Badges
0    7LBCS        New Reviewer - 1 Review
1    8FKME        New Reviewer - 1 Review; New Photographer - 1 Photo; Reviewer - 3 Reviews;
当我使用以下方法时:

df['Badges'] = df.apply(lambda row: set(row['Badges']), axis=1)

我为上面数据框中的每一行获得的输出是一个集合,其中包含该行中字符串的唯一字符。我无法复制精确的输出,因为出于某种原因,一旦生成输出,Spyder IDE就会崩溃。但第一行的输出类似于:

{'1', '-', 'N', 'e', 'w', 'R', 'v', 'i', 'r'}

转换为集合时可能会出现什么问题?

在使用集合之前,必须先拆分:

In [11]: df.Badges.str.split('\s*;\s*').apply(set)
Out[11]:
0                            {New Reviewer - 1 Review}
1    {Reviewer - 3 Reviews, , New Photographer - 1 ...
Name: Badges, dtype: object
要扔掉空的,我可以调整如下:

In [12]: df.Badges.str.split('\s*;\s*').apply(lambda bs: set(b for b in bs if b))
Out[12]:
0                            {New Reviewer - 1 Review}
1    {Reviewer - 3 Reviews, New Photographer - 1 Ph...
Name: Badges, dtype: object
或者你可以去掉“;”首先(如果那是唯一一个空的地方):


后者可能会稍微更有效…

在使用set之前,您必须先拆分:

In [11]: df.Badges.str.split('\s*;\s*').apply(set)
Out[11]:
0                            {New Reviewer - 1 Review}
1    {Reviewer - 3 Reviews, , New Photographer - 1 ...
Name: Badges, dtype: object
要扔掉空的,我可以调整如下:

In [12]: df.Badges.str.split('\s*;\s*').apply(lambda bs: set(b for b in bs if b))
Out[12]:
0                            {New Reviewer - 1 Review}
1    {Reviewer - 3 Reviews, New Photographer - 1 Ph...
Name: Badges, dtype: object
或者你可以去掉“;”首先(如果那是唯一一个空的地方):


后者的效率可能会稍高一些……

您的数据格式不便于使用。我建议对Andy的代码进行扩展,使每个条目都有自己的行,这样您就可以更高效地过滤数据

str.split
开始,然后使用
str.extract
提取键值对

df = df.set_index('R_id')\
       .Badges.str.split('\s*;\s*', expand=True)\
       .stack().reset_index(level=1, drop=1)\
       .str.extract('(?P<Name>[^-]+).*(?P<Val>\d+)', expand=True)\
       .dropna()

print(df)
                    Name Val
R_id                        
7LBCS      New Reviewer    1
8FKME      New Reviewer    1
8FKME  New Photographer    1
8FKME          Reviewer    3
df=df.set\u索引('R\u id'))\
.Badges.str.split('\s*;\s*',expand=True)\
.stack().reset_索引(级别=1,下降=1)\
.str.extract(“(?P[^-]+).*P\d+”,expand=True)\
.dropna()
打印(df)
名称Val
注册号
7LBCS新审核人1
8FKM新审阅者1
8FKME新摄影师1
8FKM审查员3

一小时的痛苦可能一个世纪的收获。

您的数据格式不便于处理。我建议对Andy的代码进行扩展,使每个条目都有自己的行,这样您就可以更高效地过滤数据

str.split
开始,然后使用
str.extract
提取键值对

df = df.set_index('R_id')\
       .Badges.str.split('\s*;\s*', expand=True)\
       .stack().reset_index(level=1, drop=1)\
       .str.extract('(?P<Name>[^-]+).*(?P<Val>\d+)', expand=True)\
       .dropna()

print(df)
                    Name Val
R_id                        
7LBCS      New Reviewer    1
8FKME      New Reviewer    1
8FKME  New Photographer    1
8FKME          Reviewer    3
df=df.set\u索引('R\u id'))\
.Badges.str.split('\s*;\s*',expand=True)\
.stack().reset_索引(级别=1,下降=1)\
.str.extract(“(?P[^-]+).*P\d+”,expand=True)\
.dropna()
打印(df)
名称Val
注册号
7LBCS新审核人1
8FKM新审阅者1
8FKME新摄影师1
8FKM审查员3

一个小时的痛苦可能一个世纪的收获。

你在寻找什么子字符串?例如,GiantSlovedAthmetal,我正在寻找“新评论员”,但为了我的真正目的,我需要搜索大约50个不同的子字符串。有些行包含大约400个描述符,如“新审阅者”、“审阅者”、“新摄影师”等。注意:转换为
set
将删除重复的实例。@Rnovice如果您的问题得到了回答,请回答。否则,请要求澄清。请注意,您只能接受一个答案,但可以对所有答案进行投票。您要查找的子字符串是什么?@GiantSlovedAthmetal例如,我正在寻找“新评论员”,但出于我的真正目的,我需要搜索大约50个不同的子字符串。有些行包含大约400个描述符,如“新审阅者”、“审阅者”、“新摄影师”等。注意:转换为
set
将删除重复的实例。@Rnovice如果您的问题得到了回答,请回答。否则,请要求澄清。请注意,您只能接受一个答案,但可以对所有答案进行投票。尽管我不完全理解代码的作用,但在看到输出后,我认为此建议对实现我的最终目标更有帮助。但是,我有两个问题。这可以在不将R_id设置为索引的情况下完成吗?这样,我以后就可以使用R_id列进行排序了。此外,Val字段当前仅捕获描述后的一个数字。在某些情况下,我有一些类似专家评审员的东西——110条评审。我如何修改上面的代码以捕获110而不是1?另外,为什么我不能使用以下命令过滤新df中的行:df[df.Name==“new Reviewer”]。该命令返回一个空数据帧。@Rnovice yes和yes。对于第一个问题,请调用df=df.reset_index()。对于name列,使用df.name=df.name.str.strip(),我认为您有尾随空格,之后应该可以进行过滤。尽管我不完全理解代码的作用,但在看到输出后,我认为这个建议对实现最终目标更有帮助。但是,我有两个问题。这可以在不将R_id设置为索引的情况下完成吗?这样,我以后就可以使用R_id列进行排序了。此外,Val字段当前仅捕获描述后的一个数字。在某些情况下,我有一些类似专家评审员的东西——110条评审。我如何修改上面的代码以捕获110而不是1?另外,为什么我不能使用以下命令过滤新df中的行:df[df.Name==“new Reviewer”]。该命令返回一个空数据帧。@Rnovice yes和yes。对于第一个问题,请调用df=df.reset_index()。对于name列,使用df.name=df.name.str.strip(),我认为您有尾随空格,过滤应该在后面进行。