일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 빅데이터
- 알고리즘
- VAE
- Graph
- 강화학습
- pytorch
- PYTHON
- GNN
- 크롤링
- DATA
- 데이터분석
- 텍스트분석
- 논문리뷰
- 우분투
- dropout
- 불확실성
- 리눅스
- YarinGal
- R
- 코딩테스트
- selenium
- AI
- 베이지안
- 백준
- pandas
- uncertainty
- 파이썬
- bayesian
- 텍스트마이닝
- Crawling
- Today
- Total
끄적거림
[Pandas] 서로 길이가 다른 list/Series 합쳐서 DataFrame 만들기 in python & R 본문
[Pandas] 서로 길이가 다른 list/Series 합쳐서 DataFrame 만들기 in python & R
Signing 2020. 8. 13. 10:28데이터를 만지다보면 여러 array형 데이터(list/Series in python, vector in R)를 합쳐서 새로운 dataframe 형태로 만들 경우가 생긴다.
보통의 경우 길이가 같은 array들을 이어 붙여야 우리가 원하는 딱 맞는 이쁜 데이터프레임 객체가 생성된다.
하지만 항상 그럴 경우만 생기지는 않으니, 길이가 서로 다른 1차원 자료형을 붙여 dataframe형태로 만들때를 생각해보자!
너무도 당연한 이야기이지만 서로 다른 길이의 1차원 자료형을 붙이면 제일 긴 길이의 데이터를 가지고 데이터프레임 객체가 생성될 것이고, 빈 공간은 NA로써 혹은 Nan 혹은 Null값으로 채워지길 바란다.
우선 R이 편하니 R부터 해보자.
1. R - cbind
다음과 같은 길이가 다른 객체들이 있다.
a <- 1:8
b <- 1:10
c <- letters[1:6]
이들을 모두 합치기 위해서는 처음으로 생각드는 것은 data.frame 객체에 바로 넣는 것이다.
data.frame(A = a, B = b, C = c)
# Error in data.frame(A = a, B = b, C = c) :
# arguments imply differing number of rows: 8, 10, 6
하지만 이렇게 하면 에러가 난다.
길이가 다르기 때문에 에러가 난다고 한다.
다른 방법으로는 cbind를 두 번 사용하는 것과 do.call 함수를 사용하는 것이다.
# R
# method 1: double cbind
cbind(cbind(a,b), c)
# method 2: do.call function
do.call(cbind, list(a,b,c))
# Same Result
# a b c
# [1,] "1" "1" "a"
# [2,] "2" "2" "b"
# [3,] "3" "3" "c"
# [4,] "4" "4" "d"
# [5,] "5" "5" "e"
# [6,] "6" "6" "f"
# [7,] "7" "7" "a"
# [8,] "8" "8" "b"
# [9,] "1" "9" "c"
# [10,] "2" "10" "d"
이번엔 warning이 뜨면서 결과가 위와 같이 나오긴 한다.
cbind를 두 사용하는 것에서 일단 마음에 안드는 것이 1) cbind 두 번 사용 2) na값이 아닌 다른 값.
warning 메세지는 그렇다쳐도 Na값이 아닌 값이 채워지는 것은 왜 그럴까?
그 이유는 바로 Recycle Rule이 적용되었기 때문이다.
Recycle Rule이란, R이 연산을 진행할 때, 길이가 부족한 데이터를 알아서 채워주는 연산방법이다.
R 자체적으로 내장되어있기 때문에 이 부분에 유의해서 진행해야한다.(이 부분은 나중에 따로 포스팅할 예정)
또한 cbind를 두 번 사용하는 것이 다소 좀 거슬린다.
지금은 객체가 3개이기에 두번 사용했지만, 객체가 N개라면 N-1번을 해야할 상황이다.
이를 위해 등장한 것이 do.call 함수이다.(이 함수에 대해서도 포스팅 예정)
어쨌든 내가 원하던 결과는 이 것이 아니다. 제대로 하려면 다음과 같다.
length(a) <- max(length(a),length(b),length(c))
length(b) <- max(length(a),length(b),length(c))
length(c) <- max(length(a),length(b),length(c))
do.call(cbind, list(a,b,c))
# [,1] [,2] [,3]
# [1,] "1" "1" "a"
# [2,] "2" "2" "b"
# [3,] "3" "3" "c"
# [4,] "4" "4" "d"
# [5,] "5" "5" "e"
# [6,] "6" "6" "f"
# [7,] "7" "7" NA
# [8,] "8" "8" NA
# [9,] NA "9" NA
# [10,] NA "10" NA
더 번거로움이 생긴다. 어쨌든 완성은 했다.
그럼 이제 파이썬에서는 어떻게 하는지 확인해보자.
다음과 같이 데이터를 만든다.
a = [i for i in range(6)]
b = [i for i in range(10)]
c = [i for i in range(8)]
그리고 이 객체들을 dictonary로 묶어준다.
dic = {
'A' : a,
'B' : b,
'C' : c
}
# Out[6]:
# {'A': [0, 1, 2, 3, 4, 5],
# 'B': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
# 'C': [0, 1, 2, 3, 4, 5, 6, 7]}
그리고 아래의 코드대로 진행해주면 된다.
res = pd.DataFrame.from_dict(dic, orient='index')
Out[10]:
# 0 1 2 3 4 5 6 7 8 9
# A 0 1 2 3 4 5 NaN NaN NaN NaN
# B 0 1 2 3 4 5 6.0 7.0 8.0 9.0
# C 0 1 2 3 4 5 6.0 7.0 NaN NaN
하지만 원하던 행과 열이 아니기 때문에 이를 바꿔준다.
res = res.transpose()
res
# Out[12]:
# A B C
# 0 0.0 0.0 0.0
# 1 1.0 1.0 1.0
# 2 2.0 2.0 2.0
# 3 3.0 3.0 3.0
# 4 4.0 4.0 4.0
# 5 5.0 5.0 5.0
# 6 NaN 6.0 6.0
# 7 NaN 7.0 7.0
# 8 NaN 8.0 NaN
# 9 NaN 9.0 NaN
그럼 해결!
'Python > Data Handling' 카테고리의 다른 글
[DataFrame] 여러 DataFrame 가볍게 append하기 in python (0) | 2020.11.26 |
---|---|
[문자열 다루기] 문자(한글, 영문)와 숫자만 남기고 특수문자 제거하기 in python (1) | 2020.11.26 |
python DataFrame 데이터 합치기 (0) | 2020.11.20 |
[데이터셋] PHD08 한글 손글씨 이미지 데이터 (1) | 2020.10.26 |
[Tips] 조건걸고 새로운 컬럼 추가하기 in Pandas DataFrame (5) | 2020.08.10 |