识别Python df中特定数字格式中的随机输入字符

识别Python df中特定数字格式中的随机输入字符,python,pandas,Python,Pandas,我必须用membership_id清理列,但是,有很多随机输入值,如“0000000”、“99999”、“*”和“na” 成员id是序列号。成员ID的格式从4位到12位不等,其中: 4位-9位数字从任何非零数字开始,而10到12位数字从1000xxxxxxxx开始 很抱歉在开始时没有清楚地描述格式,我刚刚发现未能满足此条件的ID是无效的。我想将所有这些非会员id格式区分为0,谢谢帮助 member_id 1 176828287 2 17

我必须用membership_id清理列,但是,有很多随机输入值,如“0000000”、“99999”、“*”和“na”

成员id是序列号。成员ID的格式从4位到12位不等,其中:

4位-9位数字从任何非零数字开始,而10到12位数字从1000xxxxxxxx开始

很抱歉在开始时没有清楚地描述格式,我刚刚发现未能满足此条件的ID是无效的。我想将所有这些非会员id格式区分为0,谢谢帮助

         member_id
 1      176828287         
 2      176841791         
 3      202142958         
 4      222539874         
 5      223565464         
 6      224721631         
 7      227675081         
 8      30235355118       
 9        %                  
10      ---                
11      .                  
12      .215694985         
13      0                  
14      00                 
15      000                
16      00000000000000     
17      99999999999999     
18      999999999999999    
19      : 211066980        
20      D5146159           
21      JulieGreen         
22      N/a                
23      NONE               
24      None               
25      PP - Premium Pr    
26      T0000              
27      T0000019           
28      T0000022           

您是否已经创建了一个正则表达式,该正则表达式满足要用0替换的数据的条件?如果没有,您必须创建一个,或者为要替换的单个项创建一个字典
terms={'N/a':0'--':0}
,然后调用该系列。

如果我理解正确,使用regex表达式=
\a((1000\d{8})|([1-9]\d{3,10}))\Z
将满足您的要求

上面的正则表达式与下面的匹配:

  • 1000开头的12位数字

  • 4到11位,必须以
    1开头

  • 下面是一个演示:

    import pandas as pd
    import re
    
    df = pd.DataFrame(['176828287','176841791','202142958','222539874','223565464','224721631','227675081','30235355118',
      '%','---','.','.215694985','0','00','000','00000000000000','99999999999999','999999999999999',':211066980',
      'D5146159','JulieGreen','N/a','NONE','None','PP - PremiumPr','T0000','T0000019','T0000022'], columns=['member_id'])
    
    r = re.compile(r'\A((1000\d{8})|([1-9]\d{3,10}))\Z')
    df['valid'] = df['member_id'].apply(lambda x: bool(r.match(x)))
    #you can use df['member_id'] = df['member_id'].apply(lambda x: x if bool(r.match(x)) else 0) to replace invalid id with 0
    print(df)
    
              member_id  valid
    0         176828287   True
    1         176841791   True
    2         202142958   True
    3         222539874   True
    4         223565464   True
    5         224721631   True
    6         227675081   True
    7       30235355118   True
    8                 %  False
    9               ---  False
    10                .  False
    11       .215694985  False
    12                0  False
    13               00  False
    14              000  False
    15   00000000000000  False
    16   99999999999999  False
    17  999999999999999  False
    18       :211066980  False
    19         D5146159  False
    20       JulieGreen  False
    21              N/a  False
    22             NONE  False
    23             None  False
    24   PP - PremiumPr  False
    25            T0000  False
    26         T0000019  False
    27         T0000022  False
    
    输出

    import pandas as pd
    import re
    
    df = pd.DataFrame(['176828287','176841791','202142958','222539874','223565464','224721631','227675081','30235355118',
      '%','---','.','.215694985','0','00','000','00000000000000','99999999999999','999999999999999',':211066980',
      'D5146159','JulieGreen','N/a','NONE','None','PP - PremiumPr','T0000','T0000019','T0000022'], columns=['member_id'])
    
    r = re.compile(r'\A((1000\d{8})|([1-9]\d{3,10}))\Z')
    df['valid'] = df['member_id'].apply(lambda x: bool(r.match(x)))
    #you can use df['member_id'] = df['member_id'].apply(lambda x: x if bool(r.match(x)) else 0) to replace invalid id with 0
    print(df)
    
              member_id  valid
    0         176828287   True
    1         176841791   True
    2         202142958   True
    3         222539874   True
    4         223565464   True
    5         224721631   True
    6         227675081   True
    7       30235355118   True
    8                 %  False
    9               ---  False
    10                .  False
    11       .215694985  False
    12                0  False
    13               00  False
    14              000  False
    15   00000000000000  False
    16   99999999999999  False
    17  999999999999999  False
    18       :211066980  False
    19         D5146159  False
    20       JulieGreen  False
    21              N/a  False
    22             NONE  False
    23             None  False
    24   PP - PremiumPr  False
    25            T0000  False
    26         T0000019  False
    27         T0000022  False
    

    pandas
    具有内置的字符串函数,其中包括模式匹配算法。
    因此,您可以轻松创建布尔掩码,以区分有效id和无效id:

    pattern = r'1000\d{6,8}$|[1-9]\d{3,8}$'
    mask = df.member_id.str.match(pattern)
    
    要仅打印有效行,只需使用掩码作为索引:

    print(df[mask])
    
        member_id
    1  176828287                                                
    2  176841791                                                
    3  202142958                                                
    4  222539874                                                
    5  223565464                                                
    6  224721631                                                
    7  227675081                                                    
    
    要将无效数据设置为
    0
    ,只需使用掩码的补码:

    df.loc[~mask] = 0
    print(df)
    
        member_id                                               
    1   176828287                                               
    2   176841791                                              
    3   202142958                                               
    4   222539874                                               
    5   223565464                                             
    6   224721631                                               
    7   227675081                                             
    8           0                                             
    9           0                                           
    10          0                                            
    11          0                                             
    12          0
    13          0
    14          0
    15          0
    16          0
    17          0
    18          0
    19          0
    20          0
    21          0
    22          0
    23          0
    24          0
    25          0
    26          0
    27          0
    28          0
    

    奇怪-此模式不符合要求。Tbh我不理解接受。@SpghttCd因为OP说
    302355118
    是一个有效的ID,可能它没有很好地描述标准,特别是对于这个规则=
    ,而从10到12位数字是从1000xxxxxxxx开始的。但是方法是一样的,只需要对正则表达式进行一点调整就可以了。但是,您是否至少应该更新它,以便重新模式匹配最新的需求?在我的印象中,他们不是一个再专家(除此之外:“新投稿人”),因此可能无法或至少不太了解细节,无法应用这些小更正。@SpghttCd lol,但我看到OP@you然后说它确实符合要求,尽管OP后来删除了该评论,并在您的答案中添加了一条评论。这就是为什么我说OP没有正确描述它的标准。很抱歉我编辑了这些描述。由于没有明确的标准,我只是从现有的数据集中找到了它。我是新来的,抱歉搞混了。:)我理解这一点——不要误解我的意思,你可以选择你最喜欢的任何解决方案(当然,我觉得我的解决方案比@Sphinx的更干净,我可以想象它更高效,但这还没有得到证实)。然而,这两种解决方案都可以工作,但对于这两种解决方案来说,正则表达式模式完全满足您的需求是至关重要的。否则你最终会被错误地删除id和误报。