如何在pandas DataFrame中找到与正则表达式匹配的实际唯一值

时间:2016-04-08 15:24:05

标签: python regex pandas normalization

我有一个超过一百万行的pandas DataFrame,我需要在尝试规范化数据的过程中找到所有唯一值(对于给定的列)。给定列中的数据是字符串类型 - 表示城市名称 - 我已经在标准化数据方面做了很多工作,通过采取某些步骤作为列中的所有值的下限,条带化和使用pandas.core.frame.DataFrame.replace()使用对数据来说显而易见的正则表达式。

我在下面找到的(我想要实现的)样本:

In [1018]: sample
Out[1018]: 
       0
0     warsaw   ## -> warsaw
1     krakow   ## -> krakow
2   warszawa   ## -> warsaw
3   cracovie   ## -> krakow
4    warsawa   ## -> warsaw
5      krkow   ## -> krakow
6     krąków   ## -> krakow
7   krakowie   ## -> krakow
8     kraków   ## -> krakow
9   varşovia   ## -> warsaw
10  warschau   ## -> warsaw

只有比这更大的数据集,因此我需要使用reg表达式搜索不同城市名称的变体,以便找到数据集版本中的所有数据并继续进行规范化。

In [1023]: df.column_a.unique()
Out[1023]: 
array(['warsaw', 'bydgoszcz', 'null', ..., 'kłodawa', 'kościelna wieś',
   'poznań-jeżyce'], dtype=object)

In [1024]: len(df.column_a.unique())
Out[1024]: 3798

我尝试过使用.str.contains(),但我只得到那些在定义列下具有匹配给定正则表达式的索引的布尔值:

In [1029]: df.column_a.str.contains(r"\bwar.*")
Out[1029]: 
0       True
1      False
2      False
3       True
4      False
5      False
6      False
7      False
8      False
9      False
10     False
   ...  

然而,我正在寻找的是获得与给定正则表达式匹配的实际值。对于上面的例子,我希望能得到类似的东西:

['warsaw','warszawa','warsawa','warschau']

2 个答案:

答案 0 :(得分:1)

使用布尔索引 - 请参阅document

@GET
@Path("{id}")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public User getUser(
    @PathParam("id") Integer id) throws NotFoundException {
  final String logRequest = "User retrieval request for user " + id;
  logger.info(logRequest);
  User user = userService.getById(id);

  doMyChoresThatTakeALongTime(user); // how can I make this happen *AFTER* returning the reponse?

  logger.info(logRequest + " succeeded");
  return user;
}

如果有空值,则执行以下操作:

   In [143] df[df.column_a.str.contains(r'\bwar.*')]
   Out [143]
   0     warsaw
   2   warszawa
   4    warsawa
   10  warschau

答案 1 :(得分:0)

我现在找到了一种运行搜索以在DataFrame列中返回唯一值的方法。解决方案是改为extract值。

对于这个问题,如上所述,我使用的是str.extract()而不是str.contains()

In [1311]: df.column_a.str.extract(r"\b(war.*)").unique()
Out[1311]: 
array(['warsaw', nan, 'waraszawa', 'warszawskiej', 'warszawy', 'warzawa',
   'warsza', 'warrszawa', 'warzszawa', 'warszawan', 'warszawie',
   'warwszawa', 'warszawski', 'warzno 84-208', 'warasza, wola',
   'warszawskie', 'warzsawa', 'warzno', 'warszawa', 'warszwa', 'warsawa'], dtype=object)

可能有一个更好的解决方案,但这个肯定是一个。