我一直试图解决这个问题。我正在尝试从DB_user列中删除非ASCII字符并尝试用空格替换它们。但我不断收到一些错误。这就是我的数据框的外观:
+----------------------------------------------------------- | DB_user source count | +----------------------------------------------------------- | ???/"Ò|Z?)?]??C %??J A 10 | | ?D$ZGU ;@D??_???T(?) B 3 | | ?Q`H??M'?Y??KTK$?Ù‹???ЩJL4??*?_?? C 2 | +-----------------------------------------------------------
我正在使用这个功能,这是我在研究SO上的问题时遇到的。
def filter_func(string):
for i in range(0,len(string)):
if (ord(string[i])< 32 or ord(string[i])>126
break
return ''
And then using the apply function:
df['DB_user'] = df.apply(filter_func,axis=1)
我一直收到错误:
'ord() expected a character, but string of length 66 found', u'occurred at index 2'
但是,我想通过在filter_func函数中使用循环,我通过在'ord'中输入char来处理这个问题。因此,当它命中非ASCII字符时,应该用空格替换。
有人可以帮帮我吗?
谢谢!
答案 0 :(得分:19)
你可以试试这个:
df.DB_user.replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
答案 1 :(得分:4)
您的代码失败,因为您没有在每个字符上应用它,您正在应用每个单词和ord错误,因为它需要一个字符,您需要:
df['DB_user'] = df["DB_user"].apply(lambda x: ''.join([" " if ord(i) < 32 or ord(i) > 126 else i for i in x]))
您还可以使用链式比较来简化连接:
''.join([i if 32 < ord(i) < 126 else " " for i in x])
您还可以使用string.printable
过滤字符:
from string import printable
st = set(printable)
df["DB_user"] = df["DB_user"].apply(lambda x: ''.join([" " if i not in st else i for i in x]))
最快的是使用翻译:
from string import maketrans
del_chars = " ".join(chr(i) for i in range(32) + range(127, 256))
trans = maketrans(t, " "*len(del_chars))
df['DB_user'] = df["DB_user"].apply(lambda s: s.translate(trans))
有趣的是,这比以下更快:
df['DB_user'] = df["DB_user"].str.translate(trans)
答案 2 :(得分:1)
这里给出的几个答案是不正确的。简单验证:
s = pd.Series([chr(x) for x in range(256)])
s.loc[0]
>> '\x00'
s.replace({r'[^\x00-\x7F]+':''}, regex=True).loc[0]
>> '\x00' # FAIL
s.str.encode('ascii', 'ignore').str.decode('ascii').loc[0]
>> '\x00' # FAIL
s.apply(lambda x: ''.join([i if 32 < ord(i) < 126 else " " for i in x])).loc[0]
>> ' ' # Success!
import string
s.apply(lambda x: ''.join([" " if i not in string.printable else i for i in x])).loc[0]
>> ' ' # Looks good, but...
s.apply(lambda x: ''.join([" " if i not in string.printable else i for i in x])).loc[11]
>> '\x0b' # FAIL
del_chars = " ".join([chr(i) for i in list(range(32)) + list(range(127, 256))])
trans = str.maketrans(del_chars, " " * len(del_chars))
s.apply(lambda x: x.translate(trans)).loc[11]
>> ' ' # Success!
结论:仅(已接受答案)(来自Padraic Cunningham)中的选项可靠地工作。他的第二个答案中有一些奇怪的Python错误/错别字,在此进行了修改,但否则应该是最快的。
答案 3 :(得分:0)
这对我有用:
import re
def replace_foreign_characters(s):
return re.sub(r'[^\x00-\x7f]',r'', s)
df['column_name'] = df['column_name'].apply(lambda x: replace_foreign_characters(x))
答案 4 :(得分:0)
一个常见的技巧是使用errors="ignore"
标志执行ASCII编码,然后将其解码为ASCII:
df['DB_user'].str.encode('ascii', 'ignore').str.decode('ascii')
从python3.x及更高版本开始,这是我推荐的解决方案。
最小代码示例
s = pd.Series(['Déjà vu', 'Ò|zz', ';test 123'])
s
0 Déjà vu
1 Ò|zz
2 ;test 123
dtype: object
s.str.encode('ascii', 'ignore').str.decode('ascii')
0 Dj vu
1 |zz
2 ;test 123
dtype: object
P.S .:这也可以扩展到需要过滤掉不属于任何字符编码方案(不仅仅是ASCII)的字符的情况。
答案 5 :(得分:0)
这对我有用。鉴于该系列有一些 NaN
值,它仅对字符串执行:
from string import printable
import pandas as pd
df["text_data"] = df["text_data"].str.split().str.join(' ')
df["text_data"] = df["text_data"].apply(lambda string_var: ''.join(filter(lambda y: y in printable, string_var)) if isinstance(string_var, str) else string_var)
答案 6 :(得分:0)
from string import printable
def printable_mapper(x):
return ''.join([_ if _ in printable else " " for _ in x])
df.DB_user = df.DB_user.map(printable_mapper)