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.

注意:值不能像dictslists那样是types,因为它们的dtypesobject.

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)

谢谢!