I want to flip any specific bit of a dataframe that also doesn't affect the neighbour bits. For example, my dataframe look like this,
s = pd.Series(["01100", "10010", "11100", "10011"])
0 01100
1 10010
2 11100
3 10011
Now, I want it as (after flipping only the 3rd bit),
0 01000
1 10110
2 11000
3 10111
I know how to flip last position bit using panda string slice but not any specific position.
CodePudding user response:
Applying a python function that does that for every entry
s.apply(lambda s: bin(int(s, 2)^(2**(3-1)))[2:].zfill(len(s)))
Concatenating concatenating the flipped bit with the unchanged part
s.str.slice(0,-3) s.str.slice(-3,-2).replace('0', 'a').replace('1', '0').replace('a', '1') s.str.slice(-2)
CodePudding user response:
One way is to use Series.str
methods:
s = s.str.slice(stop=2) (1-s.str.get(2).astype(int)).astype(str) s.str.slice(start=3)
print(s):
0 01000
1 10110
2 11000
3 10111
dtype: object
CodePudding user response:
Integers are a more natural representation than str
for this
binary bit-flipping exercise.
You call it "the 3rd bit", but conventionally we name it the 2nd,
reserving the zeroth bit for the low-order units position.
We wish to flip the k
th bit with ^
XOR.
import pandas as pd
from functools import partial
fmt = partial(str.format, '{0:08b}')
k = 2
df = pd.DataFrame(dict(n=s.apply(int, base=2)))
df['binary'] = df.n.apply(fmt)
df['flipped'] = (df.n ^ 2 ** k).apply(fmt)
>>> df
n binary flipped
0 12 00001100 00000100
1 18 00010010 00011010
2 28 00011100 00010100
3 19 00010011 00011011
CodePudding user response:
here is one way to do it use regex
#partitioned the string, so you can point out the bit you want to flip
# check the value of the bit, and accordingly flip with if-else
s.str.replace(r'(..)(.)(.*)',
lambda x: x.group(1)
('0' if x.group(2)=='1' else '1')
x.group(3), regex=True )
0 01000
1 10110
2 11000
3 10111
dtype: object