데이터 프레임의 모든 문자열 제거 / 자르기


80

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

이것은 매우 느립니다. 무엇을 개선 할 수 있습니까?


1
df.replace(r'\s*(.*?)\s*', r'\1', regex=True)
MaxU

1
이것은 단지 @MaxU에 의해-로그인하여 답을 기록 최선의 답이다
Linkon

답변:


151

를 사용 DataFrame.select_dtypes하여 string열을 선택한 다음 apply기능 할 수 있습니다 str.strip.

주의 : 값이 될 수 없다 types처럼 dictslists자신 때문에 dtypesIS 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()

1
설명 된대로 그리고 SettingWithCopyWarning이 경우 무시해야 stackoverflow.com/questions/20625582/...
하비

71

머니 샷

다음 은 값이 문자열 유형 인 경우에만 applymap호출하기 위해 간단한 람다 식과 함께 사용하는 간단한 버전입니다 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


1
안녕하세요 @DaleKube ... 나는 방금 온전한 검사로 새 컴퓨터 에서이 신선한 것을 시도했고 대답에 게시 된 것과 동일한 결과를 얻었습니다. Python2 또는 Python3을 사용하고 있는지 확인할 수 있습니까? 나는 요즘 Python3 만 사용하고 있지만 아마도 그 요인이 될 수 있습니다. 그렇다면 내 게시 된 답변에서 확인할 수 있는지 알려 드리겠습니다. 감사!
Jonathan B.

1
내 댓글을 삭제했습니다. 코드에서 버그를 발견했고 이제 매력처럼 작동하는지 확인할 수 있습니다. 참고로, 저는 Python 3을 사용하고 있습니다. 불편을 끼쳐 드려 죄송합니다.
Dale Kube 2017

당신이 사용해야 type(x) == str하지,type(x) is str
fjsj

@fjsj 넛지 주셔서 감사합니다. PEP8 지침을 사용하여 예제를 업데이트했습니다 isinstance(x, str).
Jonathan B.

10

당신은 시도 할 수 있습니다:

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())

9

정말 정규식을 사용하려면

>>> df.replace('(^\s+|\s+$)', '', regex=True, inplace=True)
>>> df
   0   1
0  a  10
1  c   5

그러나 다음과 같이하는 것이 더 빠릅니다.

>>> df[0] = df[0].str.strip()

5

개체 의 apply기능 을 사용할 수 있습니다 Series.

>>> 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 개체 의 apply기능 을 사용 합니다.

>>> 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

1
df[0] = df[0].str.strip()-아마도 더 큰 DF에서 더 빠를 것입니다
MaxU

-1
def trim(x):
    if x.dtype == object:
        x = x.str.split(' ').str[0]
    return(x)

df = df.apply(trim)

1
기능이 무엇을하는지 설명해 주시겠습니까?
CJ Dennis

예를 들어, 일상 업무에서 다음과 같은 데이터를 접하게됩니다. 가나다 봻 공백의 왼쪽 부분은 내가 원하는 것이고 오른쪽 부분은 쓰레기입니다. 트림 기능은 원시 데이터에서 원하는 것을 추출합니다.
정현우

이것은 문자열을 자르지 않기 때문에 반대 투표로, 첫 번째 공백 다음의 모든 것을 제거합니다. 이것은 질문에서 요구하는 행동이 아니며 독자가 기대하지 않을 수있는 부작용을 소개합니다. 또한 부작용이 즉시 나타나지 않을 수도 있습니다. 성 열을 잘라내려는 경우 대부분의 사람들이 여러 성을 가지고 있지 않고 후행 공백이 제거 되었기 때문에 의도 한대로 작동한다고 생각할 수 있습니다. 그런 다음 두 개의 성을 가진 포르투갈어 사람이 사이트에 가입하고 코드는 성을 제거하고 이름 만 남겨 둡니다.
scottclowe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.