【问题标题】:Pandas regex comprehension - isolate single result熊猫正则表达式理解 - 隔离单个结果
【发布时间】:2021-02-10 13:54:11
【问题描述】:

我有一个从 SQL 服务器中提取的数据框,我使用正则表达式来提取三个维度的字符串。我需要三个新列中的所有三个维度,因此我使用了一个正则表达式来选择由句点分隔的数字,并从此 findall 结果创建了一个列。但结果显示为列表,我无法索引第二个维度。由于紧迫性,我已经能够通过环顾来暂时解决这个问题。但是如何直接提取

维度列提取 - 并非所有都采用这种格式

[1103.5 x 308.8 x 25.4 mm]
[33.3 x 13 x 9.5mm]
[136.5 x 15 x 12.7 mm]

查找暗淡的代码提取

dims = re.compile(r'.*mm', flags=re.I)
x_dim = re.compile(r'^([0-9]*\.?[0-9]?)', flags=re.I)
y_dim = re.compile(r'(\d+\.?\d?)', flags=re.I)
# y_dim = re.compile(r'(?<=x\s)(\d+\.?\d?)(?=\sx)', flags=re.I) # lookaround solution
df['Dimensions'] = df['Part_Extended_Desc'].str.findall(dims)
df['x'] = df['Part_Extended_Desc'].str.findall(x_dim)
df['y'] = df['Part_Extended_Desc'].str.findall(y_dim)
df['trial'] = df['y'][0][1] # does not work
df['second_dim'] = df.dim_list.apply(lambda x:x[1]) # also doesn't work (list index out of range)
print(df.tail(50))

使用 findall 结果的示例输出

[1493.4, 204.2, 25.4, 0013, 900, 4]
[136.5, 15, 12.7, 001, 900, 2]

我需要 1493.4 的列和 204.2 的第二列 - 我可以做第一列,但是如何为正则表达式结果中的特定索引创建列。我已经尝试过 lambda、列表理解以及我能想到的所有其他方法。

到目前为止,我在网上找不到类似的问题,我知道它应该很简单 - 但花了我 2 天时间!

非常感谢您的帮助

编辑:

为了确认,最初的正则表达式结果并不总是采用相同的格式,有时为 zz.zmm x zz.zmm x zmm,有时为 zz x zz mm,在许多情况下,最好提取一个列表只有数字,而不是强大的特定正则表达式模式。

此外,我的重点是仅将列表项 n 获取到新列,而不是列表中的每个项

【问题讨论】:

    标签: python regex pandas dataframe


    【解决方案1】:

    如果我理解正确,您正在寻找扩展列保存列表的方法,假设所有记录中的匹配数相等,您可能会这样做:

    import pandas as pd
    df = pd.DataFrame({'dim':['10x10','12x10','10x12']})
    df['dim_list'] = df.dim.str.findall(r'\d+')
    df[['width','height']] = df.dim_list.apply(pd.Series)
    print(df)
    

    输出:

         dim  dim_list width height
    0  10x10  [10, 10]    10     10
    1  12x10  [12, 10]    12     10
    2  10x12  [10, 12]    10     12
    

    如果只需要第 n 个元素,您可以使用 lambda 以下方式:

    df['second_dim'] = df.dim_list.apply(lambda x:x[1])
    

    【讨论】:

    • 谢谢,这很有帮助 - 如果每个列表有 n 个对象但您只需要,比如第 5 个,那该怎么办?
    • 谢谢,这是我自己尝试的方法,但输出消息是“IndexError: string index out of range”
    • 或“列表索引超出范围” - 取决于我是否尝试引用原始字符串或从中派生的正则表达式列表
    • @damien1991 这意味着您的记录中的列表元素少于您的预期
    • 是的,如上所述,从中提取的原始字符串变化很大,这就是为什么我需要将数字隔离为浮点数,然后如果有超过 2 个浮点数,则隔离第二个。也许这可以在有条件的 try/except 循环中工作?
    【解决方案2】:

    如果你有答案中显示的格式,你可以使用

    import pandas as pd
    df = pd.DataFrame({'Dimensions':['1103.5 x 308.8 x 25.4 mm','33.3 x 13 x 9.5mm','136.5 x 15 x 12.7 mm']})
    >>> df[['Height','Width','Length']] = df['Dimensions'].str.extract(r'(\d+(?:\.\d+)?)\s*x\s*(\d+(?:\.\d+)?)\s*x\s*(\d+(?:\.\d+)?)\s*mm\b')
    >>> df
                       Dimensions  Height  Width Length
    0    1103.5 x 308.8 x 25.4 mm  1103.5  308.8   25.4
    1           33.3 x 13 x 9.5mm    33.3     13    9.5
    2        136.5 x 15 x 12.7 mm   136.5     15   12.7
    

    regex demo

    详情

    • (\d+(?:\.\d+)?) - 第 1 组:一个数字
    • \s*x\s* - 一个 x 包含 0+ 个空格
    • (\d+(?:\.\d+)?) - 第 2 组:一个数字
    • \s*x\s* - 一个 x 包含 0+ 个空格
    • (\d+(?:\.\d+)?) - 第 3 组:一个数字
    • \s* - 0+ 个空格
    • mm\b - 一个完整的词mm

    【讨论】:

      猜你喜欢
      • 2020-11-14
      • 2021-03-06
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 2018-04-30
      • 2021-07-09
      • 1970-01-01
      相关资源
      最近更新 更多