在python中使用正则表达式查找特定的数字模式

在python中使用正则表达式查找特定的数字模式,python,regex,dataframe,Python,Regex,Dataframe,我想用带有NaN的正则表达式替换数据帧列中以“-99”开头的所有值,因为这些是异常值 我使用了df['Item'].replace(r(^[-][9][9]\d.*$),np.NaN),但它不起作用。不知道熊猫是什么,但是您显示的代码没有引号,当然正则表达式也没有按照您说的做\d*$表示它必须以数字结尾,后跟任何字符。也许你是说 df['Item'].替换(r'^-99\..*',np.NaN) 其中,^锚点表示行的开头(或者,这里是单元格的开头),而-99仅与文本匹配。最后,\.匹配一个文字

我想用带有
NaN
的正则表达式替换数据帧列中以“-99”开头的所有值,因为这些是异常值


我使用了
df['Item'].replace(r(^[-][9][9]\d.*$),np.NaN)
,但它不起作用。

不知道熊猫是什么,但是您显示的代码没有引号,当然正则表达式也没有按照您说的做
\d*$
表示它必须以数字结尾,后跟任何字符。也许你是说

df['Item'].替换(r'^-99\..*',np.NaN)
其中,
^
锚点表示行的开头(或者,这里是单元格的开头),而
-99
仅与文本匹配。最后,
\.
匹配一个文字点,
*
匹配其后的任何内容,直到单元格结束。

TL;博士
@tripleee
发布的正则表达式可以检测以
-99开头的数字(编码为字符串)。
这里的问题是您处理的是数字,而正则表达式只适用于字符串

MCVE 让我们构建一个全面的示例:

import numpy as np
import pandas as pd

df = pd.DataFrame([-999, -99.9, -9, 9, 99.9, 0., 1, -999], columns=['Item'])

    Item
0 -999.0
1  -99.9
2   -9.0
3    9.0
4   99.9
5    0.0
6    1.0
7 -999.0
正则表达式 然后,您可以使用正则表达式(只要字符串格式适合)对异常值进行处理,然后只需在应用正则表达式(位于系列的toolsuite中)之前将()转换为字符串即可

但是,如果您打算使用string对象的replace函数将这些值替换为
nan
,那么它将需要额外的步骤,因为该函数需要另一个字符串,其他任何操作都不会失败(使用
np.nan
None
将失败)。然后,您必须执行:

df['Item'].astype(str).str.replace(r'^-99\..*', 'nan').astype(float)
在我看来,这是一个非常糟糕的一行,因为“不必要的”铸造破坏了数据的本质

逻辑索引 您最好使用上面的布尔向量,或者用sentinel替换:

df.loc[q1] = np.nan

    Item
0 -999.0
1    NaN
2   -9.0
3    9.0
4   99.9
5    0.0
6    1.0
7 -999.0
或切片:

df = df.loc[~q1,:]

    Item
0 -999.0
2   -9.0
3    9.0
4   99.9
5    0.0
6    1.0
7 -999.0
无论如何,将数字转换为字符串来检测异常值似乎有点奇怪(性能差,复杂的行为难以调试,数据的额外拷贝)

浮点运算 简单过滤器 如果没有理由认为小于
-99.
的数字仍然有效,则可以使用简单的数字标准将其过滤掉:

q2 = df['Item'] <= -99.
df = df.loc[~q2,:]

   Item
2  -9.0
3   9.0
4  99.9
5   0.0
6   1.0

当然,您可以更改
目标
,并使机器精度方面的
ε
尽可能小。

数字3位数长吗?我不太了解熊猫,但可能尝试使用r'^[-][9][9]\d.*$”而不是r(^[-][9][9]\d.*$)。字符串前的r表示原始字符串,我以前没有在括号前见过它。你有一个应该匹配和不应该匹配的示例字符串吗?我们可以看到这些列的数据类型是什么?@MindFlow我取消了你的一些编辑。请不要对非代码的内容使用
代码格式设置
。@MindFlow谢谢您的建议。这是我关于StackOverflow的第一个问题;我犯了一个错误。@jlandercy列的类型是float64,该特定值是以-99开头的列中的异常值。后面跟着更多的数字。我想用NaN替换它,然后用NaN列的平均值替换它。我对pandas和regex不太熟悉,无法用regex计算出匹配的数字。如果你的数据是数字,那么regex几乎肯定是错误的工具。您必须将每个字符串转换为字符串,然后在该字符串上使用正则表达式;但对于数值运算来说,这太疯狂了——只需检查它是否小于-99(或大于-100,但如果这些都是您所说的异常值,那么这可能是不必要的)。如果你想寻找真正的文本模式,比如检查每一个第二个数字是否都是相同的数字或类似的东西,那么在数字上使用正则表达式才有意义。谢谢你的详细回答,我真的认为正则表达式会是一个更好的选择,尽管你的解释让我现在更好地理解了为什么它不是一个好的选择。我最终使用了
temperature.loc[temperature.MAX\u TEMP<-90,'MAX\u TEMP']=np.nan
条件,解决了我的问题。
q2 = df['Item'] <= -99.
df = df.loc[~q2,:]

   Item
2  -9.0
3   9.0
4  99.9
5   0.0
6   1.0
target = -99.5
epsilon = 0.5
q3 = np.abs(df['Item'] - target) <= epsilon

0    False
1     True
2    False
3    False
4    False
5    False
6    False
7    False