Определите случайные входные символы среди определенного числового формата в python df

Мне пришлось очистить столбец с помощью members_id, однако есть много случайных входных значений, таких как '0000000', '99999', '*', 'na'.

Member_id - это серийные номера. Формат идентификатора участника варьируется от 4 до 12 цифр, в котором:

4 цифры - 9 цифр начинаются с любого ненулевого числа, а от 10 до 12 цифр начинаются с 1000xxxxxxxx.

Извините за нечеткое описание формата в начале, я только что обнаружил, что идентификаторы, не соответствующие этим критериям, являются недопустимыми. Я хотел бы выделить все эти идентификаторы, не относящиеся к членству, как 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           
1
0
51
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

У вас есть уже созданное регулярное выражение, удовлетворяющее критериям данных, которые вы хотите заменить на 0? Если нет, вам придется либо создать его, либо создать словарь terms = {'N/a':0, '---':0} отдельных элементов, которые вы хотите заменить, а затем вызвать .map (условия) в серии.

Ответ принят как подходящий

Если я правильно понял, использование выражение регулярного выражения = \A((1000\d{8})|([1-9]\d{3,10}))\Z будет соответствовать вашим требованиям.

Вышеупомянутое выражение регулярного выражения соответствует ниже:

  1. 12 цифр, начинающихся с 1000

  2. От 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

Странно - этот узор не соответствует требованиям. Tbh я не понимаю принятия.

SpghttCd 13.09.2018 22:11

@SpghttCd, поскольку OP сказал, что 30235355118 является действительным идентификатором, вероятно, он не очень хорошо описывает критерии, особенно для этого правила = while from 10 to 12 digits are starting from 1000xxxxxxxx. Но подход будет таким же, просто нужно немного настроить выражение регулярного выражения для критериев.

Sphinx 13.09.2018 22:30

Однако разве вы не должны хотя бы обновить его, чтобы повторный шаблон соответствовал последним требованиям OP? На мой взгляд, они не являются повторным экспертом (помимо этого: «Новый участник»), поэтому, возможно, не могут или, по крайней мере, недостаточно осведомлены о деталях, чтобы внести небольшие исправления.

SpghttCd 14.09.2018 06:23

@SpghttCd lol, но я видел OP @, после чего вы сказали, что он соответствует требованиям, хотя OP удалил этот комментарий позже и добавил один комментарий к вашему ответу. Вот почему я сказал, что, возможно, OP неправильно описал свои критерии.

Sphinx 14.09.2018 07:00

pandas имеет встроенные строковые функции, которые включают алгоритмы сопоставления с образцом. Таким образом, вы можете легко создать логическую маску, которая отличает действительный идентификатор от недопустимого:

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

Извините за редактирование описаний. Поскольку четких критериев нет, я просто понял это из существующего набора данных. Я здесь новенький, извините за недоразумение. :)

Jenny Jing Yu 13.09.2018 22:26

Я понимаю это - и не поймите меня неправильно, вы можете выбрать любое решение, которое вам больше нравится (хотя, конечно, я, естественно, считаю, что мое решение чище, чем у @Sphinx, и я могу представить, что оно даже более эффективно, но это не доказано пока что). Однако оба решения жестяная банка работают, но для обоих важно, чтобы шаблон регулярного выражения точно отвечал вашим требованиям. В противном случае вы получите ошибочно удаленные идентификаторы и ложные срабатывания.

SpghttCd 14.09.2018 06:26

Другие вопросы по теме