我可以在每个单元格都是列表列表的 Python Pandas 列上使用正则表达式搜索或匹配吗?

Can I use regular expressions search or match on a Python Pandas column where each cell is a list of lists?

我有一个有点大的 CSV 文件(>2,000 行),我已阅读 Pandas 并且想根据特定单词是否出现在其中一个数据列中来创建一个新的指示器列.我一直在尝试使用正则表达式搜索,这可能有点矫枉过正,因为这个词总是会被空格分开,但 DataFrame 的单元格是字符串列表的列表。我已经尝试使用双列表理解进行迭代,但存在错误,而且我也很好奇,作为一个 Python 新手,是否有一个通用的解决方案可以将未指定数量的嵌套列表展平。这是一个示例,我的最终目标是在所选列的单元格中 anywhere 出现单词 'saddle' 的行中包含 1 的新列,和 0 如果不是。

我的 DataFrame 看起来像这样

import pandas as pd
import numpy as np

cycling = pd.DataFrame(
    {
        'qty' : [1,0,2,1,1],
        'item' : ['frame','frame',np.nan,'order including a saddle and other things','brake'],
        'desc' : [np.nan,['bike','wheel'],['bike',['tire','tube']],['saddle',['seatpost','bag']],['bike','brakes']]
    }
)

Here is the DataFrame

我可以搜索item栏来实现我的目标,使用这段代码(效率和其他建议非常欢迎!!):

cycling['saddle1'] = [int(bool(re.search(r"saddle",x))) for x in cycling['item'].replace(np.nan,'missing')]

我的原始数据集有缺失值,我想在指标列中将其解析为 0;否则我不关心他们。上面的代码非常适合每个单元格 the fourth row is correctly identified 中包含字符串的列,但我无法修改它以在单元格包含列表或列表列表(如 desc 列)时工作。我试过了:

cycling['saddle2'] = [int(bool(re.search(r"saddle",x))) for y in cycling['desc'].replace(np.nan,'missing') for x in y]

但我收到以下错误

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-45-4c72cdaa87a4> in <module>()
----> 1 cycling['saddle2'] = [int(bool(re.search(r"saddle",x))) for y in cycling['desc'].replace(np.nan,'missing') for x in y]
      2 cycling.head()

1 frames
/usr/lib/python3.6/re.py in search(pattern, string, flags)
    180     """Scan through string looking for a match to the pattern, returning
    181     a match object, or None if no match was found."""
--> 182     return _compile(pattern, flags).search(string)
    183 
    184 def sub(pattern, repl, string, count=0, flags=0):

TypeError: expected string or bytes-like object

我认为错误是它不喜欢接收正则表达式的非字符串(也许是未展平的列表?)。有没有一种方法可以在 Pandas 的列中搜索特定的单词(可能使用正则表达式),其中一些单元格是字符串列表,一些是还包含嵌套列表的字符串列表,一些单元格丢失,以创建一个指示器列,它出现的任何地方都带有 1(无论是否嵌套),否则 0

您可以使用 map 而不是 运行 for 循环(它很慢)。您可以将列表转换为 str 以调用正则表达式。像这样:-

import pandas as pd
import numpy as np
import re

cycling = pd.DataFrame(
    {
        'qty' : [1,0,2,1,1],
        'item' : ['frame','frame',np.nan,'order including a saddle and other things','brake'],
        'desc' : [np.nan,['bike','wheel'],['bike',['tire','tube']],['saddle',['seatpost','bag']],['bike','brakes']]
    }
)
cycling['saddle1'] = cycling['item'].replace(np.nan,'missing').map(lambda x :int(bool(re.search(r"saddle",x))))
cycling['saddle2'] = cycling['desc'].replace(np.nan,'missing').map(lambda x :int(bool(re.search(r"saddle",str(x)))))

cycling

希望对您有所帮助!!1