【问题标题】:Remove special characters in a pandas column using regex使用正则表达式删除熊猫列中的特殊字符
【发布时间】:2019-01-09 12:57:49
【问题描述】:

我正在使用一个 pandas 数据框,其中一列中包含非数值。有没有一种方法可以只替换字符,同时保留列中的数字。我对应用正则表达式模式来清理数据和非常感谢有人能指出我正确的正则表达式模式。

最终输出必须是 [0-9].[0-9] 类型的单个数字浮点数,但也会有不遵循这些标准的值,我需要找到这些数字然后缩放它们.

例如:

Col A

'7.8.',
'5..3',
'%3.2',
'   ',
'3.*8',
'3.8*',
'140',
'14.5 of HGB',
'>14.5',
'<14.5',
'14,5'
'14. 5'

预期输出:

Col A

'7.8',
'5.3',
'3.2',
'0',
'3.8',
'3.8',
'140',
'14.5',
'14.5',
'14.5',
'14.5',
'14.5'

附:目的是只提取数字,然后将其转换为浮点数,以便我可以对其进行一些计算。

谢谢,

阿卜杜勒

【问题讨论】:

  • 您的预期输出是什么? 3.*8应该是3.8和5..3应该是5.3吗??
  • 1.2.3 呢?变成123、12.3、1.23...?
  • 建议的第一步:替换所有不是数字或句点的内容,然后从那里开始。 unallowed = re.compile(r'[^\d\.]'),然后是s.str.replace(unallowed, '')
  • @RafaelC 如果是这种情况,那么我只需要第一个出现的点并将其用作值。 1.2.3 然后转换为 1.2 忽略 .3
  • @ALollz 是的,预期输出的格式必须为 [0-9].[0-9],所有特殊字符均已删除。3.*8 必须为 3.8 和 5.. 3 必须是 5.3。如果它的值像 140,那么我只需要保持原样并将其转换为浮点数,以便我以后可以缩放它。

标签: python regex pandas dataframe


【解决方案1】:

正则表达式将“。”两侧的数字分组。忽略所有非数字。代码使用这些组来创建所需的输出。 Regex101

import pandas as pd

def clean_input(m):
    print(m.group(0))
    if m:
        val = m.group(1)
        if m.group(2):
            val = val + '.' +m.group(2)
    return val

a = pd.DataFrame({'colA':
   ['7.8.',
    '5..3',
    '%3.2',
    '   ',
    '3.*8',
    '3.8*',
    '140',
    '5.5.',
    '14.5 of HGB',
    '>14.5',
    '<14.5',
    '14,5',
   '14. 5']})
a['colA'].str.replace('[^\d]*(\d+)[^\d]*(?:\.)?[^\d]*(\d)*[^\d]*', clean_input)

输出:

0      7.8
1      5.3
2      3.2
3         
4      3.8
5      3.8
6      140
7      5.5
8     14.5
9     14.5
10    14.5
11    14.5
12    14.5

正则表达式解释:

  • \d - 匹配一个数字
  • [^&lt;pattern&gt;] - 匹配除
  • [^\d] - 匹配除数字以外的任何字符。
  • [^\d]+- 匹配上述一项或多项。
  • (?:) - 是未捕获匹配字符的非捕获组。
  • &lt;pattern&gt;? - 模式出现 0 次或 1 次。
  • \. - 因为. 是一个元字符,它必须用\ 转义

【讨论】:

  • 你能评论一下这不起作用的值吗?也许,您可以将其添加到问题中。
  • 这几乎解决了我的问题。我仍然有一些值,其中包含很少的文本和某些符号。我不知道如何提出格式 [0] 以外的唯一值-9].[0-9] 和我在那里列出的示例是基于我尝试过并遇到错误的正则表达式。我还有更多问题出现。如何从 HGB 的 14.5 中提取数据,>14.5,
  • 感谢您的更新。我用额外的输入运行代码,它似乎工作。你能再检查一次吗?
  • 非常感谢您的解决方案。这确实像一个魅力。您能否详细解释一下这个正则表达式,以便我将来可以应用它。?
【解决方案2】:

另一种做法:用句点分割字符串,从第一个和第二个片段中提取所有数字,用句点连接它们。

parts = df['colA'].str.split('\.')
part0 = parts.str[0].str.extract('(\d+)').fillna('0')
part1 = parts.str[1].str.extract('(\d+)').fillna('0')
part0 + "." + part1

输出:

#0    7.8
#1    5.0
#2    3.2
#3    0.0
#4    3.8
#5    3.8
#6  140.0

【讨论】:

    猜你喜欢
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多