현상

  • 상황 : pandas의 두 데이터프레임을 merge 했을 때
  • 현상 : 특정 컬럼의 값이 float64로 자동으로 변경됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd

user_data = {
    "user_id" : ["0001", "0002", "0003", "0004", "0005"],
    "name" : ["john", "mike", "merry", "poppins", "jenny"],
    "age" : [20, 30, 40, 50, 60]
}

purchase_history = {
    "user_id" : ["0001", "0002", "0001", "0004", "0005", "0006"],
    "item_id" : ["IT01", "IT33", "IT13", "IT99", "IT62", "IT43"],
    "price" : [3000, 52000, 950, 4350, 800, 5550]
    }

user_df = pd.DataFrame(user_data)
purchase_history_df = pd.DataFrame(purchase_history)
merge_pu = purchase_history_df.merge(user_df, on="user_id", how="left")

print("===== user_df =====")
print(user_df.info())
print("===== merge =====")
print(merge_pu.info())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 출력
===== user_df =====
Data columns (total 3 columns):
 i   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   user_id  5 non-null      object
 1   name     5 non-null      object
 2   age      5 non-null      int64      # <<<< 원래 int64형 
dtypes: int64(1), object(2)

===== merge =====
Data columns (total 5 columns):
 i   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   user_id  6 non-null      object 
 1   item_id  6 non-null      object 
 2   price    6 non-null      int64  
 3   name     5 non-null      object 
 4   age      5 non-null      float64    # <<<< float으로 바뀜
dtypes: float64(1), int64(1), object(3)

원인

  • merge 과정에서 해당 컬럼에 NaN이 포함되기 때문에 pandas가 해당 컬럼의 dtype을 float64로 자동 승격시키기 때문

해결

해결 방법 리스트

No 해결 방법
1 의도한 대로 merge를 설정한건지 검토(merge key 등)
2 NaN 값을 처리한 뒤, 해당 컬럼을 다시 int로
3 NaN이 예상되는 컬럼을 Int64 타입으로 관리

merge 설정 검토

  • merge 할 때 의도에 맞게 코딩을 했는지 검토한다.
  • merge key (on)은 잘 설정했는지, merge하는 df들은 정상인지 등

NaN값 처리 후 int로 변환

  • NaN값을 적절한 값으로 처리한다 : 제거, 대치, 보간
  • 이후 해당 컬럼을 다시 int 형으로 변환한다.
1
2
3
4
merge_pu = purchase_history_df.merge(user_df, on="user_id", how="left")
merge_pu["age"] = merge_pu["age"].fillna(99) # 대치
merge_pu["age"].astype("int64")              # 변환
print(merge_pu.info())
1
2
3
4
5
6
7
8
9
10
# 출력
Data columns (total 5 columns):
 i   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   user_id  6 non-null      object
 1   item_id  6 non-null      object
 2   price    6 non-null      int64 
 3   name     5 non-null      object
 4   age      6 non-null      int64 
dtypes: int64(2), object(3)

Int64 데이터타입 사용

  • Int64 데이터타입은, NaN값을 허용하는 데이터타입이다.
1
2
3
user_df["age"] = user_df["age"].astype("Int64")
merge_pu = purchase_history_df.merge(user_df, on="user_id", how="left")
print(merge_pu.info())
1
2
3
4
5
6
7
8
9
10
# 출력
Data columns (total 5 columns):
 i   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   user_id  6 non-null      object
 1   item_id  6 non-null      object
 2   price    6 non-null      int64 
 3   name     5 non-null      object
 4   age      5 non-null      Int64 
dtypes: Int64(1), int64(1), object(3)

Comments