programing

데이터 프레임 문자열 열에 결측값이 있는 경우 소문자를 지정하는 방법은 무엇입니까?

css3 2023. 7. 19. 21:30

데이터 프레임 문자열 열에 결측값이 있는 경우 소문자를 지정하는 방법은 무엇입니까?

다음 코드가 작동하지 않습니다.

import pandas as pd
import numpy as np
df=pd.DataFrame(['ONE','Two', np.nan],columns=['x']) 
xLower = df["x"].map(lambda x: x.lower())

xLower = ['one','two',np.nan]을(를) 얻으려면 어떻게 조정해야 합니까? 실제 데이터 프레임이 크기 때문에 효율성이 중요합니다.

설명서에서와 같이 판다 벡터화된 문자열 방법을 사용합니다.

이러한 메서드는 결측값/NA 값을 자동으로 제외합니다.

.str.lower()첫 번째 예입니다.

>>> df['x'].str.lower()
0    one
1    two
2    NaN
Name: x, dtype: object

열에 문자열뿐만 아니라 숫자도 포함된 경우 가능한 또 다른 해결책은 다음과 같습니다.astype(str).str.lower()또는to_string(na_rep='')그렇지 않으면 숫자가 문자열이 아니라는 점을 감안할 때, 숫자를 낮추면 반환되기 때문입니다.NaN따라서:

import pandas as pd
import numpy as np
df=pd.DataFrame(['ONE','Two', np.nan,2],columns=['x']) 
xSecureLower = df['x'].to_string(na_rep='').lower()
xLower = df['x'].str.lower()

그러면 다음과 같습니다.

>>> xSecureLower
0    one
1    two
2   
3      2
Name: x, dtype: object

그리고 아닌

>>> xLower
0    one
1    two
2    NaN
3    NaN
Name: x, dtype: object

편집:

만약 당신이 NaN을 잃고 싶지 않다면, 지도를 사용하는 것이 더 나을 것입니다, (@wojciech-walczak, 그리고 @cs95 코멘트에서) 이것은 이렇게 보일 것입니다.

xSecureLower = df['x'].map(lambda x: x.lower() if isinstance(x,str) else x)

Pandas >= 0.25: 사례 구분 제거str.casefold

v0.25부터는 유니코드 데이터를 다루는 경우 "벡터화된" 문자열 방법을 사용하는 것이 좋습니다(문자열이나 유니코드에 상관없이 작동함).

s = pd.Series(['lower', 'CAPITALS', np.nan, 'SwApCaSe'])
s.str.casefold()

0       lower
1    capitals
2         NaN
3    swapcase
dtype: object

관련 GitHub 문제 GH25405도 참조하십시오.

casefold더 공격적인 대소문자 비교에 적합합니다.또한 NaN을 우아하게 처리합니다.str.lower수행).

하지만 왜 이게 더 좋을까요?

유니코드에서는 차이가 나타납니다.파이썬 문서의 예를 들어보면,

케이스 폴딩은 소문자와 비슷하지만 문자열에서 모든 대소문자 구분을 제거하기 위한 것이기 때문에 더 공격적입니다.예를 들어, 독일어 소문자'ß'와 동등합니다."ss"이미 소문자이기 때문에,lower()에 아무런 도움이 되지 않을 것입니다'ß';casefold()로 변환합니다."ss".

의 출력을 비교합니다.lower위해서,

s = pd.Series(["der Fluß"])
s.str.lower()

0    der fluß
dtype: object

casefold,

s.str.casefold()

0    der fluss
dtype: object

또한 문자열 일치 및 소문자로 변환 시 소문자() 대 대 소문자()를 참조하십시오.

당신도 이것을 시도할 수 있습니다.

df= df.applymap(lambda s:s.lower() if type(s) == str else s)

람다 함수 적용

df['original_category'] = df['original_category'].apply(lambda x:x.lower())

가능한 해결책:

import pandas as pd
import numpy as np

df=pd.DataFrame(['ONE','Two', np.nan],columns=['x']) 
xLower = df["x"].map(lambda x: x if type(x)!=str else x.lower())
print (xLower)

결과:

0    one
1    two
2    NaN
Name: x, dtype: object

하지만 효율성에 대해서는 잘 모르겠습니다.

목록 이해력을 사용하고 있을 수 있습니다.

import pandas as pd
import numpy as np
df=pd.DataFrame(['ONE','Two', np.nan],columns=['Name']})
df['Name'] = [str(i).lower() for i in df['Name']] 

print(df)

데이터 프레임 열을 복사하여 간단히 적용

df=data['x']
newdf=df.str.lower()

적용 기능을 사용합니다.

Xlower = df['x'].apply(lambda x: x.upper()).head(10) 

결측값 및 기타 데이터 형식을 빈 문자열로 바꾸고 모든 문자열을 소문자로 바꿉니다.

df["x"] = df["x"].apply(lambda x: x.lower() if isinstance(x, str) else "")

결측값 및 문자열 이외의 다른 데이터 형식을 nan으로 바꾸고 모든 문자열을 소문자로 바꿉니다.

df["x"] = df["x"].apply(lambda x: x.lower() if isinstance(x, str) else np.nan)

nan 및 문자열 이외의 다른 데이터 형식은 그대로 유지하고 모든 문자열은 소문자로 만듭니다.

df["x"] = df["x"].apply(lambda x: x.lower() if isinstance(x, str) else x)

에 에.apply사용할 수도 있습니다.map

속도 면에서, 그것들은 거의 같습니다.df["x"] = df["x"].str.lower()그리고.df["x"] = df["x"].str.lower()그러나 적용/맵을 사용하면 결측값을 원하는 대로 처리할 수 있습니다.

100만 줄의 속도를 테스트했습니다.그 중 10%는nan나머지는 길이가 50입니다.

데이터 생성: Data generation

속도 비교: enter image description here

언급URL : https://stackoverflow.com/questions/22245171/how-to-lowercase-a-pandas-dataframe-string-column-if-it-has-missing-values