This will definitely slow things down for a large Series, but you can pass a ternary expression with a callable:
>>> b.apply(lambda x: x.decode('utf-8') if isinstance(x, bytes) else x)
0 123
1 434,
2 fgd
3 aas
4 442321
dtype: object
Looking at the source for .str.decode() is instructive - it just applies _na_map(f, arr) over the Series, where the function f is f = lambda x: x.decode(encoding, errors). Because str doesn't have a "decode" method to begin with, that error will become NaN. This happens in str_decode().
>>> from pandas.core.strings import str_decode
>>> from pandas.core.strings import _cpython_optimized_encoders
>>> "utf-8" in _cpython_optimized_encoders
True
>>> str_decode(b, "utf-8")
array([nan, nan, nan, nan, '442321'], dtype=object)
>>> from pandas.core.strings import _na_map
>>> f = lambda x: x.decode("utf-8")
>>> _na_map(f, b)
array([nan, nan, nan, nan, '442321'], dtype=object)
Answer from Brad Solomon on Stack OverflowThis will definitely slow things down for a large Series, but you can pass a ternary expression with a callable:
>>> b.apply(lambda x: x.decode('utf-8') if isinstance(x, bytes) else x)
0 123
1 434,
2 fgd
3 aas
4 442321
dtype: object
Looking at the source for .str.decode() is instructive - it just applies _na_map(f, arr) over the Series, where the function f is f = lambda x: x.decode(encoding, errors). Because str doesn't have a "decode" method to begin with, that error will become NaN. This happens in str_decode().
>>> from pandas.core.strings import str_decode
>>> from pandas.core.strings import _cpython_optimized_encoders
>>> "utf-8" in _cpython_optimized_encoders
True
>>> str_decode(b, "utf-8")
array([nan, nan, nan, nan, '442321'], dtype=object)
>>> from pandas.core.strings import _na_map
>>> f = lambda x: x.decode("utf-8")
>>> _na_map(f, b)
array([nan, nan, nan, nan, '442321'], dtype=object)
The problem still open in git
Caused by the line
except (TypeError, AttributeError): return na_value
Fix adding fillna
b.str.decode('utf-8').fillna(b)
Out[237]:
0 123
1 434,
2 fgd
3 aas
4 442321
dtype: object
You can use this solution implemented to pandas by Series.apply:
from Crypto.Cipher import XOR
import base64
def encrypt(key, plaintext):
cipher = XOR.new(key)
return base64.b64encode(cipher.encrypt(plaintext))
def decrypt(key, ciphertext):
cipher = XOR.new(key)
return cipher.decrypt(base64.b64decode(ciphertext))
load['Encoded_Column'] = load['F'].apply(lambda x: encrypt('password',x))
load['Decoded_Column'] = (load['Encoded_Column'].apply(lambda x: decrypt('password', x))
.str.decode("utf-8"))
print (load)
A B C D E F Encoded_Column Decoded_Column
0 a 4 7 1 5 a b'EQ==' a
1 b 5 8 3 3 a b'EQ==' a
2 c 4 9 5 6 a b'EQ==' a
3 d 5 4 4 9 b b'Eg==' b
4 e 5 2 2 2 b b'Eg==' b
5 f 4 0 0 4 b b'Eg==' b
Another solution:
import base64
def encode(key, clear):
enc = []
for i in range(len(clear)):
key_c = key[i % len(key)]
enc_c = chr((ord(clear[i]) + ord(key_c)) % 256)
enc.append(enc_c)
return base64.urlsafe_b64encode("".join(enc).encode()).decode()
def decode(key, enc):
dec = []
enc = base64.urlsafe_b64decode(enc).decode()
for i in range(len(enc)):
key_c = key[i % len(key)]
dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
load['Encoded_Column'] = load['F'].apply(lambda x: encode('password',x))
load['Decoded_Column'] = load['Encoded_Column'].apply(lambda x: decode('password', x))
Or use list comprehension:
load['Encoded_Column'] = [encode('password',x) for x in load['F']]
load['Decoded_Column'] = [decode('password', x) for x in load['Encoded_Column']]
print (load)
A B C D E F Encoded_Column Decoded_Column
0 a 4 7 1 5 a w5E= a
1 b 5 8 3 3 a w5E= a
2 c 4 9 5 6 a w5E= a
3 d 5 4 4 9 b w5I= b
4 e 5 2 2 2 b w5I= b
5 f 4 0 0 4 b w5I= b
import pandas as pd
import binascii
load = pd.DataFrame({'A':list('abcdef'),
'B':[4,5,4,5,5,4],
'C':[7,8,9,4,2,0],
'D':[1,3,5,4,2,0],
'E':[5,3,6,9,2,4],
'F':[binascii.hexlify(x.encode()) for x in 'aaabbb']
})
A B C D E F
0 a 4 7 1 5 b'61'
1 b 5 8 3 3 b'61'
2 c 4 9 5 6 b'61'
3 d 5 4 4 9 b'62'
4 e 5 2 2 2 b'62'
5 f 4 0 0 4 b'62'
# decode
binascii.unhexlify(load.loc[1]['F']).decode('utf-8') -->> 'a'
example
print(binascii.hexlify('HelloWorld'.encode())) --> b'48656c6c6f576f726c64'
print(binascii.unhexlify('48656c6c6f576f726c64'.encode())) --> b'HelloWorld'