본문 바로가기
Pandas

[Pandas] 하나의 컬럼을 여러개 컬럼으로 나누는 모든 방법

by 자유로운시간 2023. 10. 15.
반응형

pd.DataFrame으로 이루어진 데이터에서

문자열로 이루어진 컬럼의 값들을
구분자를 이용해서

여러 개의 컬럼으로 나누는 방법을 소개합니다.

 

 

컬럼 단위로 split 하는 방법과

로우 단위로 split 하는 방법이 있다.

 

 

여기서는 하나의 cell 값을 기준으로

컬럼 단위로는 새로운 컬럼을 생성하면서

로우 단위로는 새로운 로우를 생성하면서

데이터프레임을 나누는 여러 가지 방법을 소개한다.

 

 

pd.read_csv를 통해 데이터를 불러오고나서

구분자가 섞여있거나 pandas가 인식못하는 경우,

데이터프레임의 구성이 혼잡하게 되어 있는 경우 사용하면 좋다.

 

 

 

전제조건:

1. 컬럼의 모든 값들은 문자열로 이루어져 있어야 한다.

2. 구분자로 사용할만한 개행 및 특수 문자들이 있어야 한다. ( '\t', ',', '_', ';', ':' ... 등등)

3. 하나의 셀 안에 여러 개의 값이 있어야 한다.

 

 

 

1. 컬럼 갯수가 적은 데이터 프레임

구분자를 이용해서 컬럼을 split 해주고,

컬럼 갯수가 적기 때문에

직접 컬럼 이름을 지정해주었다.

 

import pandas as pd

two_country_df = pd.DataFrame({'국가':['대한민국, 미국','대한민국,일본']})
two_country_df

	국가
0	대한민국,미국
1	대한민국,일본



two_country_df[['나라_1','나라_2']] = two_country_df['국가'].str.split(',', expand=True)
two_country_df

	국가		나라_1		나라_2
0	대한민국,미국	대한민국	미국
1	대한민국,일본	대한민국	일본

 

 

 

2. 특정 문자열을 기준으로하여 컬럼으로 사용하고 싶은 경우

여러가지 문자열이 하나의 컬럼에 있을 때,

그 중 특정 문자열을 기준 컬럼으로 잡고,

나머지 문자열을 다른 하나의 컬럼으로 몰고 싶을때 사용한다.

country_df = pd.DataFrame({'국가':['대한민국,미국,호주,영국','대한민국,일본,중국','대한민국,베트남','대한민국,필리핀','대한민국,독일,체코,러시아,영국']})
country_df

	국가
0	대한민국,미국,호주,영국
1	대한민국,일본,중국
2	대한민국,베트남
3	대한민국,필리핀
4	대한민국,독일,체코,러시아,영국


country_df[['우리나라', '나머지국가']] = country_df['국가'].str.split(',', 1, expand=True)
country_df = country_df.drop(columns=['국가'])
country_df

	우리나라		나머지국가
0	대한민국		미국,호주,영국
1	대한민국		일본,중국
2	대한민국		베트남
3	대한민국		필리핀
4	대한민국		독일,체코,러시아,영국

 

 

 

3. 여러개의 컬럼으로 split하고나서 원하는 컬럼만 하나로 묶고 싶을 때

하나의 컬럼을 구분자를 기준으로 여러 컬럼으로 split하는 과정에서,

add_prefix 메서드를 통하여 반복 컬럼을 컨트롤 할 수 있다.

 

그리고 컬럼 인덱스를 지정해줌으로써,

원하는 컬럼만 모아서 합쳐줄 수 있다.

 

country_df = pd.DataFrame({'국가':['대한민국,미국,호주,영국','대한민국,일본,중국','대한민국,베트남','대한민국,필리핀','대한민국,독일,체코,러시아,영국']})
country_df

	국가
0	대한민국,미국,호주,영국
1	대한민국,일본,중국
2	대한민국,베트남
3	대한민국,필리핀
4	대한민국,독일,체코,러시아,영국


country_df['국가'].str.split(',', expand=True)

	0		1	2	3	4
0	대한민국	미국	호주	영국	None
1	대한민국	일본	중국	None	None
2	대한민국	베트남	None	None	None
3	대한민국	필리핀	None	None	None
4	대한민국	독일	체코	러시아	영국


### 컬럼을 2개 이상으로 multiple하게 split 해줄 때, prefix를 이용해서 컬럼 명을 지정해줄 수 있다.
country_df = country_df.join(country_df['국가'].str.split(',', expand=True).add_prefix('ID'))
country_df

	국가						ID0		ID1	ID2	ID3	ID4
0	대한민국,미국,호주,영국				대한민국	미국	호주	영국	None
1	대한민국,일본,중국				대한민국	일본	중국	None	None
2	대한민국,베트남					대한민국	베트남	None	None	None
3	대한민국,필리핀					대한민국	필리핀	None	None	None
4	대한민국,독일,이탈리아,러시아,영국,프랑스	대한민국	독일	체코	러시아	영국




### 컬럼 인덱스 2이상의 모든 컬럼을 합쳐서, 하나의 컬럼으로 만들기
country_df['나머지국가'] = country_df[country_df.columns[2:]].apply(
    lambda x : ','.join(x.dropna().astype(str)),
    axis=1)
country_df

	국가				ID0		ID1	ID2	ID3	ID4	나머지국가
0	대한민국,미국,호주,영국		대한민국	미국	호주	영국	None	미국,호주,영국
1	대한민국,일본,중국		대한민국	일본	중국	None	None	일본,중국
2	대한민국,베트남			대한민국	베트남	None	None	None	베트남
3	대한민국,필리핀			대한민국	필리핀	None	None	None	필리핀
4	대한민국,독일,체코,러시아,영국	대한민국	독일	체코	러시아	영국	독일,체코,러시아,영국

### 순서에 관계없이, 특정 컬럼을 지정해서, 하나의 컬럼으로 만들기
### 컬럼 인덱스 1번, 2번, 그리고 4번 이상의 모든 컬럼을 선택한다.
country_df['나머지국가'] = country_df[country_df.columns[[1] + [2] + list(range(4, len(country_df.columns)))]].apply(
    lambda x : ','.join(x.dropna().astype(str)),
    axis=1)
country_df

	국가				ID0		ID1	ID2	ID3	ID4	나머지국가
0	대한민국,미국,호주,영국		대한민국	미국	호주	영국	None	대한민국,미국,영국
1	대한민국,일본,중국		대한민국	일본	중국	None	None	대한민국,일본
2	대한민국,베트남			대한민국	베트남	None	None	None	대한민국,베트남
3	대한민국,필리핀			대한민국	필리핀	None	None	None	대한민국,필리핀
4	대한민국,독일,체코,러시아,영국	대한민국	독일	체코	러시아	영국	대한민국,독일,러시아,영국



country_df[['ID0','나머지국가']]

	ID0		나머지국가
0	대한민국	미국,호주,영국
1	대한민국	일본,중국
2	대한민국	베트남
3	대한민국	필리핀
4	대한민국	독일,체코,러시아,영국

 

 

 

4. 로우 단위로 split하는 예시_1

특정 컬럼을 고정시키고,

다른 컬럼의 문자열 내부의 구분자를 이용하여

로우 단위로 데이터프레임을 split한다.

 

df = pd.DataFrame({"order_id":[1,3,7],"order_date":["20/5/2018","22/5/2018","23/5/2018"], "package":["p1,p2,p3","p4","p5,p6"],"package_code":["#111,#222,#333","#444","#555,#666"]})
df

	order_id	order_date	package		package_code
0	1		20/5/2018	p1,p2,p3	#111,#222,#333
1	3		22/5/2018	p4		#444
2	7		23/5/2018	p5,p6		#555,#666


df = (df.set_index(['order_id', 'order_date'])
   .apply(lambda x: x.str.split(',').explode())
   .reset_index())
df

	order_id	order_date	package		package_code
0	1		20/5/2018	p1		#111
1	1		20/5/2018	p2		#222
2	1		20/5/2018	p3		#333
3	3		22/5/2018	p4		#444
4	7		23/5/2018	p5		#555
5	7		23/5/2018	p6		#666

 

 

5. 로우 단위로 split하는 예시_2

특정 컬럼 하나에 대하여 로우 단위로 split하는 방법

괄호()안에 지정하거나 변경할 변수가 많아서,

사용시에 유의해야 한다.

 

여기서는 데이터프레임명(df)과 컬럼명(package) 지정할 때,

유의하면 된다.

 

df = pd.DataFrame({"order_id":[1,3,7],"order_date":["20/5/2018","22/5/2018","23/5/2018"], "package":["p1,p2,p3","p4","p5,p6"],"package_code":["#111,#222,#333","#444","#555,#666"]})
df

	order_id	order_date	package		package_code
0	1		20/5/2018	p1,p2,p3	#111,#222,#333
1	3		22/5/2018	p4		#444
2	7		23/5/2018	p5,p6		#555,#666



df = \
(df.set_index(df.columns.drop('package',1).tolist())
   .package.str.split(',', expand=True)
   .stack()
   .reset_index()
   .rename(columns={0:'package'})
   .loc[:, df.columns]
)
df

	order_id	order_date	package		package_code
0	1		20/5/2018	p1		#111,#222,#333
1	1		20/5/2018	p2		#111,#222,#333
2	1		20/5/2018	p3		#111,#222,#333
3	3		22/5/2018	p4		#444
4	7		23/5/2018	p5		#555,#666
5	7		23/5/2018	p6		#555,#666

 

 

 

 

6. 복잡한 데이터프레임 split and concat 예시

df = pd.DataFrame({"ID":[6,6,6,7,7,8,8],"order_date":["21/05/2016","21/01/2014","02/04/2013","05/06/2014","12/08/2014","18/04/2012","21/03/2012"], "data":["A: 7, B: 8, C: 5, D: 5, A: 8","B: 5, C: 5, D: 7","A: 4, D:7","C: 25","D: 20","A: 2, B: 3, C: 3, E: 5, B: 4","F: 6, B: 4, F: 5, D: 6, B: 4  "]})
df

	ID	order_date	data
0	6	21/05/2016	A: 7, B: 8, C: 5, D: 5, A: 8
1	6	21/01/2014	B: 5, C: 5, D: 7
2	6	02/04/2013	A: 4, D:7
3	7	05/06/2014	C: 25
4	7	12/08/2014	D: 20
5	8	18/04/2012	A: 2, B: 3, C: 3, E: 5, B: 4
6	8	21/03/2012	F: 6, B: 4, F: 5, D: 6, B: 4


import re
from collections import defaultdict

def str_to_dict(str1):
    d = defaultdict(int)
    for k, v in zip(re.findall('[A-Z]', str1), re.findall('\d+', str1)):
        d[k] += int(v)
    return d

pd.concat([df, df['data'].apply(str_to_dict).apply(pd.Series).fillna(0).astype(int)], axis=1)

	ID	order_date	data				A	B	C	D	E	F
0	6	21/05/2016	A: 7, B: 8, C: 5, D: 5, A: 8	15	8	5	5	0	0
1	6	21/01/2014	B: 5, C: 5, D: 7	0	5	5	7	0	0
2	6	02/04/2013	A: 4, D:7	4	0	0	7	0	0
3	7	05/06/2014	C: 25	0	0	25	0	0	0
4	7	12/08/2014	D: 20	0	0	0	20	0	0
5	8	18/04/2012	A: 2, B: 3, C: 3, E: 5, B: 4	2	7	3	0	5	0
6	8	21/03/2012	F: 6, B: 4, F: 5, D: 6, B: 4	0	8	0	6	0	11





### reverse
df = pd.DataFrame([
        [6, "a: 1, b: 2"],
        [6, "a: 1, b: 2"],
        [6, "a: 1, b: 2"],
        [6, "a: 1, b: 2"],
    ], columns=['ID', 'dictionary'])

def str2dict(s):
    split = s.strip().split(',')
    d = {}
    for pair in split:
        k, v = [_.strip() for _ in pair.split(':')]
        d[k] = v
    return d

df.dictionary.apply(str2dict).apply(pd.Series)

	a	b
0	1	2
1	1	2
2	1	2
3	1	2


pd.concat([df, df.dictionary.apply(str2dict).apply(pd.Series)], axis=1)

	ID	dictionary	a	b
0	6	a: 1, b: 2	1	2
1	6	a: 1, b: 2	1	2
2	6	a: 1, b: 2	1	2
3	6	a: 1, b: 2	1	2

 

 

Reference

1. https://www.google.com/search?q=split+one+column+to+multiple+pandas&sca_esv=573518520&biw=1920&bih=931&ei=-SQrZY6ZMNXT2roP9e6-UA&oq=Pandas+one+column+split+m&gs_lp=Egxnd3Mtd2l6LXNlcnAiGVBhbmRhcyBvbmUgY29sdW1uIHNwbGl0IG0qAggAMgYQABgIGB4yBhAAGAgYHkjIQVCqA1jULHAIeAGQAQCYAY4BoAHlB6oBAzAuOLgBA8gBAPgBAcICChAAGEcY1gQYsAPCAgUQABiABMICBhAAGAcYHsICBxAAGA0YgATCAggQABgIGAcYHsICBRAhGKAB4gMEGAAgQYgGAZAGCg&sclient=gws-wiz-serp#kpvalbx=_syUrZaegCYOJ-QaQtqy4Aw_25 

 

🔎 split one column to multiple pandas: Google 검색

 

www.google.com

2. https://thats-it-code.com/pandas/how-to-split-one-column-to-multiple-columns/

 

How to Split One Column to Multiple Columns in Pandas

Examples of how to split one column to multiple columns in Pandas using str.split(), str.extract() and regular expressions.

thats-it-code.com

3. https://suy379.tistory.com/126

 

python 열의 문자열을 분리해 N개 열로 만드는 방법(str, split, get)

오늘은 python에서 문자열 데이터를 처리할 때의 꿀팁 중 하나인, 열 이름을 관리하는 방법에 대해 포스팅한다. 이 방법은 하나의 열에 여러 의미가 있는 경우, 이 열의 정보를 분리하여 새로운 N

suy379.tistory.com

4.https://stackoverflow.com/questions/48958282/how-do-i-split-a-string-into-several-columns-in-a-dataframe-with-pandas-python

 

How do I split a string into several columns in a dataframe with pandas Python?

I am aware of the following questions: 1.) How to split a column based on several string indices using pandas? 2.) How do I split text in a column into multiple rows? I want to split these into s...

stackoverflow.com

5.https://passwd.tistory.com/entry/Python-Pandas-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%9E%90%EB%A5%B4%EA%B8%B0%EC%8A%AC%EB%9D%BC%EC%9D%B4%EC%8B%B1

 

[Python] Pandas - 문자열 컬럼 분할 및 다중 컬럼 추가

개요 데이터를 전처리하다 보면 문자열 컬럼을 분할하여 컬럼을 여러 개 추가해야 하는 경우가 많다. 이 글에서는 아래 데이터를 이용해 주소 컬럼을 분할해 도시와 구로 추가하는 방법을 몇 가

passwd.tistory.com

6.https://stackoverflow.com/questions/50731229/split-cell-into-multiple-rows-in-pandas-dataframe

 

Split cell into multiple rows in pandas dataframe

I have a dataframe contains orders data, each order has multiple packages stored as comma separated string [package & package_code] columns I want to split the packages data and create a row for

stackoverflow.com

7.https://stackoverflow.com/questions/38384145/pandas-dataframe-splitting-one-column-into-multiple-columns

반응형