TypeError:期望的字符串或类似字节的对象pandas变量

时间:2016-09-13 12:08:29

标签: python regex

我有像这样的数据集

import pandas as pd
df = pd.DataFrame({'word': ['abs e learning ', 'abs e-learning', 'abs e&learning', 'abs elearning']})

我想要

      word
0   abs elearning
1   abs elearning
2   abs elearning
3   abs elearning

我吼叫

re_map = {r'\be learning\b': 'elearning', r'\be-learning\b': 'elearning', r'\be&learning\b': 'elearning'}
import re
for r, map in re_map.items():
            df['word'] = re.sub(r, map, df['word'])

和错误

TypeError                                 Traceback (most recent call last)
<ipython-input-42-fbf00d9a0cba> in <module>()
      3 s = df['word']
      4 for r, map in re_map.items():
----> 5             df['word'] = re.sub(r, map, df['word'])

C:\Users\Edward\Anaconda3\lib\re.py in sub(pattern, repl, string, count, flags)
    180     a callable, it's passed the match object and must return
    181     a replacement string to be used."""
--> 182     return _compile(pattern, flags).sub(repl, string, count)
    183 
    184 def subn(pattern, repl, string, count=0, flags=0):

TypeError: expected string or bytes-like object

我可以像这样应用str

for r, map in re_map.items():
            df['word'] = re.sub(r, map, str(df['word']))

没有错,但我不能按照自己的意愿获得pd.dataFrame

    word
0   0 0 0 abs elearning \n1 abs elearning\...\n1 0 0 abs elearning \n1 abs elearning\...\n2 0 0 abs elearning \n1 abs ele...
1   0 0 0 abs elearning \n1 abs elearning\...\n1 0 0 abs elearning \n1 abs elearning\...\n2 0 0 abs elearning \n1 abs ele...
2   0 0 0 abs elearning \n1 abs elearning\...\n1 0 0 abs elearning \n1 abs elearning\...\n2 0 0 abs elearning \n1 abs ele...
3   0 0 0 abs elearning \n1 abs elearning\...\n1 0 0 abs elearning \n1 abs elearning\...\n2 0 0 abs elearning \n1 abs ele...

如何改善它?

1 个答案:

答案 0 :(得分:2)

df['word']是一个列表。转换为字符串只会破坏您的列表。

您需要对每个成员应用正则表达式:

for r, map in re_map.items():
    df['word'] = [re.sub(r, map, e) for e in df['word']]:

没有列表理解的经典替代方法:

 for r, map in re_map.items():
     d = df['word']
     for i,e in enumerate(d):
         d[i] = re.sub(r, map, e)

顺便说一下,你可以大大简化你的正则表达式列表:

re_map = {r'\be[\-& ]learning\b': 'elearning'}

通过这样做,你只有一个正则表达式,这成为一个单行:

 df['word'] = [re.sub(r'\be[\-& ]learning\b', 'elearning', e) for e in df['word']]:
通过为所有替换预编译正则表达式,

甚至可以更快:

 theregex = re.compile(r'\be[\-& ]learning\b')
 df['word'] = [theregex.sub('elearning', e) for e in df['word']]: