I have data as below:

I want to mask this data as below one


So I tried below code :

 readFile = pd.read_csv("C:/Users/siddhesh.kalgaonkar/Desktop/data01.txt",header=None)
 readFile.columns = ['IP']
 readFile['IP']=readFile['IP'].str.replace("(?<! )","X").astype('str')

but I gives me data as below one which is not correct:


I am new to pandas. So where am I going wrong ?

Also, I want to do it without pandas because the platform on which I would be deploying this code may be won't have pandas. So need to be ready for the other scenario as well. Below is my code:

 finalValues = re.sub("(?<! ).","X",readFiles)  

It gives below error:

>>> finalValues = re.sub("(?<! ).","X",readFiles)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\siddhesh.kalgaonkar\AppData\Local\Programs\Python\Python36\lib\re.py", line 191, in sub
    return _compile(pattern, flags).sub(repl, string, count)
TypeError: expected string or bytes-like object

I want to split this data on the basis of delimiter (in case I have multiple columns) and then I have to apply regex logic. Please help me out here.

  • $\begingroup$ What is not correct with the readFile dataframe generated from the pd.read_csv call? Whats wrong about it? $\endgroup$
    – yoav_aaa
    Apr 11 '19 at 10:04
  • $\begingroup$ I have modified my question. Thanks for pointing out $\endgroup$
    – Debuggerrr
    Apr 11 '19 at 10:07
  • $\begingroup$ So your problem is the code replacing the '.' into X? $\endgroup$
    – yoav_aaa
    Apr 11 '19 at 10:15
  • $\begingroup$ Everything into X except first digit and '.' $\endgroup$
    – Debuggerrr
    Apr 11 '19 at 10:16

Try this if you decide to use pandas:

readFile = pd.read_csv("C:/Users/siddhesh.kalgaonkar/Desktop/data01.txt",header=None)
readFile.columns = ['IP']
readFile['IP'] = readFile['IP'].replace(regex='((?<=[0-9])[0-9]|(?<=\.)[0-9])',value='X')

and this without pandas:

readFile = open("C:/Users/siddhesh.kalgaonkar/Desktop/data01.txt","r")
for line in readFile:
    lines = line.strip()
    finalline = re.sub(pattern='((?<=[0-9])[0-9]|(?<=\.)[0-9])',repl='X',string=lines)

(?<=[0-9])[0-9] this part matches if the current position in the string is a digit and is preceded by a digit.

| or

(?<=\.)[0-9]) this part matches if the current position in the string is is a digit and is preceded by a period.

  • $\begingroup$ But what if I have multiple columns and I want to use delimiter to separate columns and then apply the logic. Can you modify your answer using without pandas.Using pandas I know how to do it $\endgroup$
    – Debuggerrr
    Apr 11 '19 at 12:36

This is pure(almost) python:

list(map(lambda x: x[0] + '.'.join(['X' * len(c) for c in x[1:].split('.')]), my_df['IP']))

- Use the map to iterate over each row in my_df['IP'] column.
- Per each IP value, split into first char and others using the x[0], x[1:]
- Get each part in x[1:] using the split method.
- For each part get its length and accordingly create a string made of X's.
- Rejoin this X's string into one string with '.' between them.

If using python2 you dont need the list.

  • $\begingroup$ Yeah, it worked can you just explain join method in detail. Also, why do we need list over here $\endgroup$
    – Debuggerrr
    Apr 11 '19 at 10:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.