판다 - 문자열 열에서 병합이 작동하지 않음(버그?)
두 데이터 프레임 간에 간단한 병합을 수행하려고 합니다.이는 두 개의 서로 다른 SQL 테이블에서 가져온 것입니다. 여기서 조인 키는 문자열입니다.
>>> df1.col1.dtype
dtype('O')
>>> df2.col2.dtype
dtype('O')
다음을 사용하여 병합을 시도합니다.
>>> merge_res = pd.merge(df1, df2, left_on='col1', right_on='col2')
내부 조인 결과가 비어 있으므로 먼저 교차점에 항목이 없을 수 있다는 메시지가 표시되었습니다.
>>> merge_res.shape
(0, 19)
하지만 제가 하나의 요소를 일치시키려고 할 때, 저는 정말 이상한 행동을 봅니다.
# Pick random element in second dataframe
>>> df2.iloc[5,:].col2
'95498208100000'
# Manually look for it in the first dataframe
>>> df1[df1.col1 == '95498208100000']
0 rows × 19 columns
# Empty, which makes sense given the above merge result
# Now look for the same value as an integer
>>> df1[df1.col1 == 95498208100000]
1 rows × 19 columns
# FINDS THE ELEMENT!?!
따라서 열은 '객체' d 유형으로 정의됩니다.문자열로 검색해도 결과가 나오지 않습니다.정수로 검색하면 결과가 반환되는데, 이것이 위에서 병합이 작동하지 않는 이유라고 생각합니다.
무슨 일인지 아십니까?
판다들이 생각하는 것과 같습니다.df1.col1
일치하는 동안 문자열로 처리되어야 하지만 가능하다는 이유만으로 정수로 변환합니다.
샘플 데이터 프레임을 사용하여 이를 복제하려고 했지만, 작은 예에서는 이 동작이 보이지 않습니다.좀 더 설명적인 예를 찾을 수 있는 방법에 대한 제안도 감사하겠습니다.)
문제는 그것이었습니다.object
dtype과 같은 형식입니다.저는 모든 물건이 끈이라는 뜻인 줄 알았습니다.하지만 분명히, 파일을 읽는 동안 판다들은 일부 요소들을 int로 변환하고 나머지 요소들은 끈으로 남겨두었습니다.
해결책은 모든 필드가 문자열인지 확인하는 것이었습니다.
>>> df1.col1 = df1.col1.astype(str)
>>> df2.col2 = df2.col2.astype(str)
그러면 병합이 예상대로 작동합니다.
(나는 다음을 지정할 수 있는 방법이 있었으면 좋겠습니다.dtype
str
...)
나는 우연히 한 사건을 만났다.df.col = df.col.astype(str)
솔루션이 작동하지 않았습니다.인코딩에 문제가 있었던 것으로 밝혀졌습니다.
원래 데이터는 다음과 같습니다.
In [72]: df1['col1'][:3]
Out[73]:
col1
0 dustin pedroia
1 kevin youkilis
2 david ortiz
In [72]: df2['col2'][:3]
Out[73]:
col2
0 dustin pedroia
1 kevin youkilis
2 david ortiz
그고사 후용리를 사용한 에..astype(str)
병합이 여전히 작동하지 않아서 다음을 실행했습니다.
df1.col1 = df1.col1.str.encode('utf-8')
df2.col2 = df2.col2.str.encode('utf-8')
그리고 그 차이를 찾을 수 있었습니다.
In [95]: df1
Out[95]:
col1
0 b'dustin\xc2\xa0pedroia'
1 b'kevin\xc2\xa0youkilis'
2 b'david\xc2\xa0ortiz'
In [95]: df2
Out[95]:
col2
0 b'dustin pedroia'
1 b'kevin youkilis'
2 b'david ortiz'
그 시점에서 내가 해야 할 일은df1.col1 = df1.col1.str.replace('\xa0',' ')
변수 df1.col1을 실행하기 전)에서.str.encode('utf-8')
완벽하게 했습니다. ) 그고리병작동습니다했게완하벽합.
참: 무고교든항사상다니습용했하체를 사용했습니다..str.encode('utf-8')
효과가 있었는지 확인하기 위해.
대안적으로
아나콘다용 스파이더 IDE에서 정규 표현식과 변수 탐색기를 사용하여 다음과 같은 차이점을 발견했습니다.
import re
#places the raw string into a list
df1.col1 = df1.col1.apply(lambda x: re.findall(x, x))
df2.col2 = df2.col2.apply(lambda x: re.findall(x, x))
여기서 df1 데이터는 다음과 같습니다(스파이더에서 복사하여 붙여넣음).
['dustin\xa0pedroia']
['kevin\xa0youkilis']
['david\xa0ortiz']
약간 다른 해결책을 가지고 있습니다.어떤 경우에 첫 번째 예시가 작동하지 않고 두 번째 예시가 작동하지 않을지 모르겠지만 누군가 부딪힐 경우를 대비해 둘 다 제공하고 싶었습니다 :)
감사합니다. @seeespi the ..str.encode('utf-8')는 아래와 같이 문자열을 제거해야 한다는 것을 이해하는 데 도움이 되었습니다.
20 b'Belize ' ... 0,612
21 b'Benin ' ... 0,546
해결책은 스트립을 사용하는 것이었습니다.
df1.col1 = df1.col1.str.strip()
df1.col1 = df1.col1.str.strip()
병합이 실제로 제대로 수행되었지만 인덱싱이 엉망이 되었기 때문에 위의 솔루션 중 어떤 것도 작동하지 않았습니다.인덱스를 제거한 것이 해결되었습니다.
df['sth'] = df.merge(df2, how='left', on=['x', 'y'])['sth'].values
이 대답으로 해결되었습니다.
pd.merge(df1.assign(x=df1.x.astype(str)),
df2.assign(x=df2.x.astype(str)),
how='left', on='x')
Pandas에서 숫자와 문자열 값을 포함하는 객체 유형 키에 대한 병합 문제
열에 차이가 있거나 공백이 있을 수 있으므로 이 오류가 발생할 수 있습니다.
먼저 열 유형과 항목 간에 차이가 있는지 확인합니다.
df1.col1 = df1.col1.str.encode('utf-8')
df2.col2 = df2.col2.str.encode('utf-8')
만약 그것들에 차이가 있다면, 당신은 사용할 수 있습니다.
df1.col1 = df1.col1.str.replace("this", "for that")
또는 빈 공간이 있는지 여부
df1.col1 = df1.col1.apply(str).str.strip()
# This apply(str) is being used because without it, the program returns an error related to being enable to convert from byte.
이 단계:
df1.col1 = df1.col1.str.strip()
df1.col1 = df1.col1.str.strip()
다음 단계를 수행합니다.
pd.merge(df1.assign(x=df1.x.astype(str)),
df2.assign(x=df2.x.astype(str)),
how='left', on='x')
저를 위해 일했습니다.둘 다 함께 말입니다.
언급URL : https://stackoverflow.com/questions/39582984/pandas-merging-on-string-columns-not-working-bug
'programing' 카테고리의 다른 글
utf8_(en|de)코드가 php7에서 제거되었습니까? (0) | 2023.07.23 |
---|---|
값의 범위에 따라 그룹화된 판다 (0) | 2023.07.23 |
자바스크립트가 있는 링크를 프로그래밍 방식으로 클릭하려면 어떻게 해야 합니까? (0) | 2023.07.23 |
Brew Services: 구성을 편집할 위치? (0) | 2023.07.23 |
스프링 부트 2.5.0 및 잘못된 정의예외: Java 8 날짜/시간 유형 'java.time.Instant'는 기본적으로 지원되지 않습니다. (0) | 2023.07.23 |