Python 剥离/修剪数据帧的所有字符串
在清理python/pandas中多类型数据帧的值时,我想修剪字符串。我目前正在按照两个说明进行操作:Python 剥离/修剪数据帧的所有字符串,python,regex,pandas,dataframe,trim,Python,Regex,Pandas,Dataframe,Trim,在清理python/pandas中多类型数据帧的值时,我想修剪字符串。我目前正在按照两个说明进行操作: import pandas as pd df = pd.DataFrame([[' a ', 10], [' c ', 5]]) df.replace('^\s+', '', regex=True, inplace=True) #front df.replace('\s+$', '', regex=True, inplace=True) #end df.values 这相当慢,
import pandas as pd
df = pd.DataFrame([[' a ', 10], [' c ', 5]])
df.replace('^\s+', '', regex=True, inplace=True) #front
df.replace('\s+$', '', regex=True, inplace=True) #end
df.values
这相当慢,我可以改进什么?您可以使用系列
对象的:
>>> df = pd.DataFrame([[' a ', 10], [' c ', 5]])
>>> df[0][0]
' a '
>>> df[0] = df[0].apply(lambda x: x.strip())
>>> df[0][0]
'a'
注意strip
的用法,而不是更快的regex
另一个选项-使用DataFrame对象的
>>> df = pd.DataFrame([[' a ', 10], [' c ', 5]])
>>> df.apply(lambda x: x.apply(lambda y: y.strip() if type(y) == type('') else y), axis=0)
0 1
0 a 10
1 c 5
您可以使用选择string
列,然后选择apply
函数
注意:值不能是类型
如dicts
或列表
,因为它们的数据类型
是对象
但如果只有几列,请使用:
如果你真的想使用正则表达式,那么
>>> df.replace('(^\s+|\s+$)', '', regex=True, inplace=True)
>>> df
0 1
0 a 10
1 c 5
但这样做应该更快:
>>> df[0] = df[0].str.strip()
您可以尝试:
df[0] = df[0].str.strip()
或者更具体地说是针对所有字符串列
non_numeric_columns = list(set(df.columns)-set(df._get_numeric_data().columns))
df[non_numeric_columns] = df[non_numeric_columns].apply(lambda x : str(x).strip())
金钱射击
下面是使用applymap
的精简版本,它带有一个简单的lambda表达式,仅当值是字符串类型时才调用strip
:
df.applymap(lambda x: x.strip() if isinstance(x, str) else x)
完整示例
一个更完整的示例:
import pandas as pd
def trim_all_columns(df):
"""
Trim whitespace from ends of each value across all series in dataframe
"""
trim_strings = lambda x: x.strip() if isinstance(x, str) else x
return df.applymap(trim_strings)
# simple example of trimming whitespace from data elements
df = pd.DataFrame([[' a ', 10], [' c ', 5]])
df = trim_all_columns(df)
print(df)
>>>
0 1
0 a 10
1 c 5
工作示例
以下是韦小宝主持的一个工作示例:
df.replace(r'\s*(.*?\s*,r'\1',regex=True)
这是最好的答案,刚刚登录并通过@MaxUdf[0]=df[0]对答案进行投票。str.strip()
-很可能在更大的DFsHi@DaleKube上会更快。。。我只是在一台新机器上尝试了这个新方法,作为一种精神检查,我得到了与答案中公布的结果相同的结果。你能确认你使用的是Python2还是Python3吗?我现在只使用Python3,但这可能是一个因素。如果是这样的话,我会在我贴出的答案中注明,如果你能确认的话。谢谢我删除了我的评论。我在我的代码中发现了一个bug,我可以确认它现在像一个符咒一样工作。仅供参考,我正在使用Python 3。很抱歉给您添麻烦。您应该使用type(x)==str
,而不是type(x)是str
@fjsj谢谢您的提示。我已经使用PEP8指南更新了示例,支持isinstance(x,str)
。请您解释一下该函数在做什么?例如,我在日常工作中遇到这样的数据:가나다 봻代码>左边空白部分是我想要的,右边是垃圾。trim函数从原始数据中提取我想要的内容。Downvoted因为它不会修剪字符串,所以会删除第一个空格后面的所有内容。这不是问题中所要求的行为,并引入了读者可能没有预料到的副作用。此外,副作用可能不会立即显现。如果您试图修剪一列姓氏,您可能会认为这是按预期进行的,因为大多数人没有多个姓氏,并且尾随空格被删除。然后一个有两个姓氏的葡萄牙人加入你的网站,代码会删除他们的姓氏,只留下他们的姓。在这种情况下,应该忽略SettingWithCopyWarning,如前所述
df.applymap(lambda x: x.strip() if isinstance(x, str) else x)
import pandas as pd
def trim_all_columns(df):
"""
Trim whitespace from ends of each value across all series in dataframe
"""
trim_strings = lambda x: x.strip() if isinstance(x, str) else x
return df.applymap(trim_strings)
# simple example of trimming whitespace from data elements
df = pd.DataFrame([[' a ', 10], [' c ', 5]])
df = trim_all_columns(df)
print(df)
>>>
0 1
0 a 10
1 c 5
def trim(x):
if x.dtype == object:
x = x.str.split(' ').str[0]
return(x)
df = df.apply(trim)