Strip / trim 数据框的所有字符串
Strip / trim all strings of a dataframe
正在清理 python/pandas 中多类型数据框的值,我想 trim 字符串。我目前正在按照两条指令进行操作:
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
这很慢,我可以改进什么?
您可以使用 Series
对象的 apply
function:
>>> df = pd.DataFrame([[' a ', 10], [' c ', 5]])
>>> df[0][0]
' a '
>>> df[0] = df[0].apply(lambda x: x.strip())
>>> df[0][0]
'a'
Note the usage of strip
and not the regex
which is much faster
另一种选择——使用DataFrame对象的apply
function:
>>> 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
您可以使用 DataFrame.select_dtypes
to select string
columns and then apply
function str.strip
.
注意:值不能像dicts
或lists
那样是types
,因为它们的dtypes
是object
.
df_obj = df.select_dtypes(['object'])
print (df_obj)
0 a
1 c
df[df_obj.columns] = df_obj.apply(lambda x: x.str.strip())
print (df)
0 1
0 a 10
1 c 5
但是如果只有几列使用str.strip
:
df[0] = df[0].str.strip()
如果你真的想使用正则表达式,那么
>>> 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
工作示例
这是一个由 trinket 托管的工作示例:
https://trinket.io/python3/e6ab7fb4ab
def trim(x):
if x.dtype == object:
x = x.str.split(' ').str[0]
return(x)
df = df.apply(trim)
怎么样(对于字符串列)
df[col] = df[col].str.replace(" ","")
永不失败
单独删除不会删除字符串中的内部额外 spaces。解决方法是先用一个 space 替换一个或多个 space。这确保我们删除额外的内部 spaces 和外部 spaces.
# Import packages
import re
# First inspect the dtypes of the dataframe
df.dtypes
# First replace one or more spaces with a single space. This ensures that we remove extra inner spaces and outer spaces.
df = df.applymap(lambda x: re.sub('\s+', ' ', x) if isinstance(x, str) else x)
# Then strip leading and trailing white spaces
df = df.apply(lambda x: x.str.strip() if isinstance(x, object) else x)
@jezrael 的回答看起来不错。但是,如果您想在最终结果集中取回其他(numeric/integer 等)列,那么您认为需要与原始 DataFrame 合并。
如果是这种情况,那么您可以使用这种方法,
df = df.apply(lambda x: x.str.strip() if x.dtype.name == 'object' else x, axis=0)
谢谢!
正在清理 python/pandas 中多类型数据框的值,我想 trim 字符串。我目前正在按照两条指令进行操作:
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
这很慢,我可以改进什么?
您可以使用 Series
对象的 apply
function:
>>> df = pd.DataFrame([[' a ', 10], [' c ', 5]])
>>> df[0][0]
' a '
>>> df[0] = df[0].apply(lambda x: x.strip())
>>> df[0][0]
'a'
Note the usage of
strip
and not theregex
which is much faster
另一种选择——使用DataFrame对象的apply
function:
>>> 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
您可以使用 DataFrame.select_dtypes
to select string
columns and then apply
function str.strip
.
注意:值不能像dicts
或lists
那样是types
,因为它们的dtypes
是object
.
df_obj = df.select_dtypes(['object'])
print (df_obj)
0 a
1 c
df[df_obj.columns] = df_obj.apply(lambda x: x.str.strip())
print (df)
0 1
0 a 10
1 c 5
但是如果只有几列使用str.strip
:
df[0] = df[0].str.strip()
如果你真的想使用正则表达式,那么
>>> 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
工作示例
这是一个由 trinket 托管的工作示例: https://trinket.io/python3/e6ab7fb4ab
def trim(x):
if x.dtype == object:
x = x.str.split(' ').str[0]
return(x)
df = df.apply(trim)
怎么样(对于字符串列)
df[col] = df[col].str.replace(" ","")
永不失败
单独删除不会删除字符串中的内部额外 spaces。解决方法是先用一个 space 替换一个或多个 space。这确保我们删除额外的内部 spaces 和外部 spaces.
# Import packages
import re
# First inspect the dtypes of the dataframe
df.dtypes
# First replace one or more spaces with a single space. This ensures that we remove extra inner spaces and outer spaces.
df = df.applymap(lambda x: re.sub('\s+', ' ', x) if isinstance(x, str) else x)
# Then strip leading and trailing white spaces
df = df.apply(lambda x: x.str.strip() if isinstance(x, object) else x)
@jezrael 的回答看起来不错。但是,如果您想在最终结果集中取回其他(numeric/integer 等)列,那么您认为需要与原始 DataFrame 合并。
如果是这种情况,那么您可以使用这种方法,
df = df.apply(lambda x: x.str.strip() if x.dtype.name == 'object' else x, axis=0)
谢谢!