Как base64 кодировать и декодировать столбец в python pandas? - PullRequest
0 голосов
/ 17 февраля 2020

Я прочитал этот пост

, кодирующий фрейм данных

, но я не хочу шифровать фрейм данных, просто конвертирую его в базу 64. Я импортирую возврат каретки список слов с разделителями в кадре данных:

words = pd.read_table("sampleText.txt",names=['word'], header=None)
words.head()

, который дает

    word
0   difference
1   where
2   mc
3   is
4   the

, затем

words['words_encoded'] = map(lambda x: x.encode('base64','strict'), words['word'])
print (words)

дал

                word                   words_encoded
0         difference  <map object at 0x7fad3e89e410>
1              where  <map object at 0x7fad3e89e410>
2                 mc  <map object at 0x7fad3e89e410>
3                 is  <map object at 0x7fad3e89e410>
4                the  <map object at 0x7fad3e89e410>
...              ...                             ...
999995  distribution  <map object at 0x7fad3e89e410>
999996            in  <map object at 0x7fad3e89e410>
999997      scenario  <map object at 0x7fad3e89e410>
999998          less  <map object at 0x7fad3e89e410>
999999          land  <map object at 0x7fad3e89e410>

[1000000 rows x 2 columns]

I не понимаю, почему мой закодированный столбец относится к объекту карты, а не к фактическим данным, поэтому я попытался:

b64words = words.word.str.encode('base64')
print(b64words)

дает

0        NaN
1        NaN
2        NaN
3        NaN
4        NaN
          ..
999995   NaN
999996   NaN
999997   NaN
999998   NaN
999999   NaN
Name: word, Length: 1000000, dtype: float64

Ну,

Это бросило меня поэтому я прочитал связанный ответ выше и попытался

import base64
def encode(text):
    return base64.b64encode(text)
words['Encoded_Column'] = [encode(x) for x in words]

, но получил

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-89-8cf5a6f1f3a9> in <module>
      2 def encode(text):
      3     return base64.b64encode(text)
----> 4 words['Encoded_Column'] = [encode(x) for x in words]

<ipython-input-89-8cf5a6f1f3a9> in <listcomp>(.0)
      2 def encode(text):
      3     return base64.b64encode(text)
----> 4 words['Encoded_Column'] = [encode(x) for x in words]

<ipython-input-89-8cf5a6f1f3a9> in encode(text)
      1 import base64
      2 def encode(text):
----> 3     return base64.b64encode(text)
      4 words['Encoded_Column'] = [encode(x) for x in words]

~/miniconda3/envs/p37cu10.2PyTo/lib/python3.7/base64.py in b64encode(s, altchars)
     56     application to e.g. generate url or filesystem safe Base64 strings.
     57     """
---> 58     encoded = binascii.b2a_base64(s, newline=False)
     59     if altchars is not None:
     60         assert len(altchars) == 2, repr(altchars)

TypeError: a bytes-like object is required, not 'str'

, поэтому я попытался преобразовать объект в байты, например, так:

import base64
def encode(text):
    btext = text.str.encode('utf-8')
    return base64.b64encode(btext)
words['Encoded_Column'] = [encode(x) for x in words]

но получил

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-90-46db6d3688ba> in <module>
      3     btext = text.str.encode('utf-8')
      4     return base64.b64encode(btext)
----> 5 words['Encoded_Column'] = [encode(x) for x in words]

<ipython-input-90-46db6d3688ba> in <listcomp>(.0)
      3     btext = text.str.encode('utf-8')
      4     return base64.b64encode(btext)
----> 5 words['Encoded_Column'] = [encode(x) for x in words]

<ipython-input-90-46db6d3688ba> in encode(text)
      1 import base64
      2 def encode(text):
----> 3     btext = text.str.encode('utf-8')
      4     return base64.b64encode(btext)
      5 words['Encoded_Column'] = [encode(x) for x in words]

AttributeError: 'str' object has no attribute 'str'

в в этом C примере они также преобразуют сначала в байтовые строки, а затем в base64, но я не могу выполнить эту простую задачу в Python. падая в эту кроличью нору, и каждая попытка все глубже и глубже. Я действительно ценю любую помощь, которую может оказать ясный человек.

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

map возвращает итератор, а не список, поэтому pandas просто назначает его всем слотам во вновь сформированном столбце "words_encoded". Точно так же, если бы вы сделали words['all_ones'] = 1, pandas присвоило бы этому столбцу 1.

Во-вторых, «base64» не является кодом c для строк, он работает на bytes. Вы должны выбрать кодировку текста, а затем кодировать это. Таким образом,

words['word_encoded'] = words.word.str.encode(
    'utf-8', 'strict').str.encode('base64')

работает, за исключением того, что этот кодировщик помещает "\ n" в конец строки base64, что я считаю странным. Вместо этого вы можете выполнить одно из следующих действий:

words['word_encoded'] = words.word.str.encode(
    'utf-8', 'strict').apply(
         base64.b64encode)

# or 

words['word_encoded'] = [base64.b64encode(x.encode('utf-8', 'strict'))
    for x in words.word]

Лично я считаю, что первый вариант немного более "pandas", поскольку он генерирует Серии напрямую без промежуточного списка.

Решение в действии

>>> import base64
>>> import pandas as pd
>>> words = pd.read_table("sampleText.txt",names=['word'], header=None)
__main__:1: FutureWarning: read_table is deprecated, use read_csv instead, passing sep='\t'.
>>> words['word_encoded'] = words.word.str.encode(
...     'utf-8', 'strict').str.encode('base64')
>>> 
>>> words
         word           word_encoded
0  difference  b'ZGlmZmVyZW5jZQ==\n'
1       where          b'd2hlcmU=\n'
2          mc              b'bWM=\n'
3          is              b'aXM=\n'
4         the              b'dGhl\n'
>>> 
>>> words['word_encoded'] = words.word.str.encode(
...     'utf-8', 'strict').apply(
...          base64.b64encode)
>>> 
>>> words
         word         word_encoded
0  difference  b'ZGlmZmVyZW5jZQ=='
1       where          b'd2hlcmU='
2          mc              b'bWM='
3          is              b'aXM='
4         the              b'dGhl'
>>> 
>>> words['word_encoded'] = [base64.b64encode(x.encode('utf-8', 'strict'))
...     for x in words.word]
>>> 
>>> words
         word         word_encoded
0  difference  b'ZGlmZmVyZW5jZQ=='
1       where          b'd2hlcmU='
2          mc              b'bWM='
3          is              b'aXM='
4         the              b'dGhl'
0 голосов
/ 17 февраля 2020

Просто удалите .str из тела функции. Истинный код:

import base64


def encode(text):
    btext = text.encode('utf-8')
    return base64.b64encode(btext)


words = {'1': 1, '2': 2, '3': 3, 'asdasd': 4}
words['Encoded_Column'] = [encode(x) for x in words]
print(words)

Вывод:

{'1': 1, '2': 2, '3': 3, 'asdasd': 4, 'Encoded_Column': [b'MQ==', b'Mg==', b'Mw==', b'YXNkYXNk']}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...