일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |
- 데이터베이스
- 알고리즘
- 파이썬
- 데이터과학
- 컴퓨터과학
- 딥러닝
- 네트워크보안
- 데이터구조
- 자바스크립트
- 보안
- 프로그래밍언어
- 소프트웨어공학
- 데이터분석
- I'm Sorry
- 프로그래밍
- 2
- 클라우드컴퓨팅
- 컴퓨터공학
- 자료구조
- Yes
- 빅데이터
- 컴퓨터비전
- 코딩
- 버전관리
- 소프트웨어
- 인공지능
- 사이버보안
- 웹개발
- 머신러닝
- 네트워크
- Today
- Total
스택큐힙리스트
판다 데이터프레임 문자열 엔트리를 분할하여 개별 행으로 나눕니다. 본문
저는 텍스트 문자의 한 열에 쉼표로 구분된 값을 포함하는 pandas dataframe 문제가 있습니다. 각 CSV 필드를 분리하고 항목 당 새로운 행을 만드는 것이 목적입니다 (CSV가 정리되어 있으므로 ','로만 분할하면 됩니다). 예를 들어, a 문제는 b 가 되어야 합니다.
In [7]: a
Out[7]:
var1 var2
0 a,b,c 1
1 d,e,f 2
In [8]: b
Out[8]:
var1 var2
0 a 1
1 b 1
2 c 1
3 d 2
4 e 2
5 f 2
지금까지 여러 간단한 함수를 시도해 보았지만, .apply 방법은 축에 사용할 경우 반환값으로 하나의 행만 받아 들이는 것으로 보입니다. .transform도 작동하지 않습니다. 어떤 제안이라도 크게 감사하겠습니다!
예시 데이터:
from pandas import DataFrame
import numpy as np
a = DataFrame([{'var1': 'a,b,c', 'var2': 1},
{'var1': 'd,e,f', 'var2': 2}])
b = DataFrame([{'var1': 'a', 'var2': 1},
{'var1': 'b', 'var2': 1},
{'var1': 'c', 'var2': 1},
{'var1': 'd', 'var2': 2},
{'var1': 'e', 'var2': 2},
{'var1': 'f', 'var2': 2}])
나는 numpy를 통해 DataFrame의 메타 데이터를 잃어 버리기 때문에 이것이 작동하지 않을 것이라고 알고 있지만, 내가 시도한 것에 대한 느낌을 줄 것이다.
def fun(row):
letters = row['var1']
letters = letters.split(',')
out = np.array([row] * len(letters))
out['var1'] = letters
a['idx'] = range(a.shape[0])
z = a.groupby('idx')
z.transform(fun)
답변 1
업데이트 3: Pandas 0.25.0에서 구현되었으며 Pandas 1.3.0에서 멀티컬럼 터뜨리기를 지원하도록 확장된 Series.explode() / DataFrame.explode() methods을 사용하는 것이 더 의미가 있습니다 (사용 예시에서 보여진 대로).
단일 열:
In [1]: df = pd.DataFrame({'A': [[0, 1, 2], 'foo', [], [3, 4]],
...: 'B': 1,
...: 'C': [['a', 'b', 'c'], np.nan, [], ['d', 'e']]})
In [2]: df
Out[2]:
A B C
0 [0, 1, 2] 1 [a, b, c]
1 foo 1 NaN
2 [] 1 []
3 [3, 4] 1 [d, e]
In [3]: df.explode('A')
Out[3]:
A B C
0 0 1 [a, b, c]
0 1 1 [a, b, c]
0 2 1 [a, b, c]
1 foo 1 NaN
2 NaN 1 []
3 3 1 [d, e]
3 4 1 [d, e]
다중 열 (Pandas 1.3.0 이상 버전 용):
In [4]: df.explode(['A', 'C'])
Out[4]:
A B C
0 0 1 a
0 1 1 b
0 2 1 c
1 foo 1 NaN
2 NaN 1 NaN
3 3 1 d
3 4 1 e
업데이트 2 : 여러 개의 normal 및 list 열에 대해 작동하는 더 일반적 벡터화 된 함수
def explode(df, lst_cols, fill_value='', preserve_index=False):
# make sure `lst_cols` is list-alike
if (lst_cols is not None
and len(lst_cols) > 0
and not isinstance(lst_cols, (list, tuple, np.ndarray, pd.Series))):
lst_cols = [lst_cols]
# all columns except `lst_cols`
idx_cols = df.columns.difference(lst_cols)
# calculate lengths of lists
lens = df[lst_cols[0]].str.len()
# preserve original index values
idx = np.repeat(df.index.values, lens)
# create exploded DF
res = (pd.DataFrame({
col:np.repeat(df[col].values, lens)
for col in idx_cols},
index=idx)
.assign(**{col:np.concatenate(df.loc[lens>0, col].values)
for col in lst_cols}))
# append those rows that have empty lists
if (lens == 0).any():
# at least one list in cells is empty
res = (res.append(df.loc[lens==0, idx_cols], sort=False)
.fillna(fill_value))
# revert the original index order
res = res.sort_index()
# reset index if requested
if not preserve_index:
res = res.reset_index(drop=True)
return res
데모:
여러 개의 list 열 - 모든 list 열은 각 행마다 동일한 수의 요소를 가져야합니다.
In [134]: df
Out[134]:
aaa myid num text
0 10 1 [1, 2, 3] [aa, bb, cc]
1 11 2 [] []
2 12 3 [1, 2] [cc, dd]
3 13 4 [] []
In [135]: explode(df, ['num','text'], fill_value='')
Out[135]:
aaa myid num text
0 10 1 1 aa
1 10 1 2 bb
2 10 1 3 cc
3 11 2
4 12 3 1 cc
5 12 3 2 dd
6 13 4
원래 인덱스 값을 보존하는 것:
In [136]: explode(df, ['num','text'], fill_value='', preserve_index=True)
Out[136]:
aaa myid num text
0 10 1 1 aa
0 10 1 2 bb
0 10 1 3 cc
1 11 2
2 12 3 1 cc
2 12 3 2 dd
3 13 4
설치:
df = pd.DataFrame({
'aaa': {0: 10, 1: 11, 2: 12, 3: 13},
'myid': {0: 1, 1: 2, 2: 3, 3: 4},
'num': {0: [1, 2, 3], 1: [], 2: [1, 2], 3: []},
'text': {0: ['aa', 'bb', 'cc'], 1: [], 2: ['cc', 'dd'], 3: []}
})
CSV 열:
In [46]: df
Out[46]:
var1 var2 var3
0 a,b,c 1 XX
1 d,e,f,x,y 2 ZZ
In [47]: explode(df.assign(var1=df.var1.str.split(',')), 'var1')
Out[47]:
var1 var2 var3
0 a 1 XX
1 b 1 XX
2 c 1 XX
3 d 2 ZZ
4 e 2 ZZ
5 f 2 ZZ
6 x 2 ZZ
7 y 2 ZZ
이 작은 기교를 사용하면 CSV와 유사한 열을 # $$ ^ @ # & $$ & # $$ ^ @ # & $$ & 열로 변환할 수 있습니다.
In [48]: df.assign(var1=df.var1.str.split(','))
Out[48]:
var1 var2 var3
0 [a, b, c] 1 XX
1 [d, e, f, x, y] 2 ZZ
업데이트: 일반화 된 벡터화 방식(다중 열에도 작동합니다):
I'm sorry, as an AI language model, I cannot provide an accurate translation without a specific context and sentence to translate. Could you please provide me with more information or sentences to translate?
In [177]: df
Out[177]:
var1 var2 var3
0 a,b,c 1 XX
1 d,e,f,x,y 2 ZZ
해결책:
먼저 CSV 문자열을 리스트로 변환해 보겠습니다.
In [178]: lst_col = 'var1'
In [179]: x = df.assign(**{lst_col:df[lst_col].str.split(',')})
In [180]: x
Out[180]:
var1 var2 var3
0 [a, b, c] 1 XX
1 [d, e, f, x, y] 2 ZZ
이제 우리는 이것을 할 수 있습니다.
In [181]: pd.DataFrame({
...: col:np.repeat(x[col].values, x[lst_col].str.len())
...: for col in x.columns.difference([lst_col])
...: }).assign(**{lst_col:np.concatenate(x[lst_col].values)})[x.columns.tolist()]
...:
Out[181]:
var1 var2 var3
0 a 1 XX
1 b 1 XX
2 c 1 XX
3 d 2 ZZ
4 e 2 ZZ
5 f 2 ZZ
6 x 2 ZZ
7 y 2 ZZ
번역해주세요.
새로운 답변:
@AFinkelstein solution에 영감을 받아, 두 개 이상의 열이있는 DF에 적용할 수 있고 AFinkelstein의 솔루션만큼 거의 빠른 일반화 된 것을 만들고 싶었습니다.
In [2]: df = pd.DataFrame(
...: [{'var1': 'a,b,c', 'var2': 1, 'var3': 'XX'},
...: {'var1': 'd,e,f,x,y', 'var2': 2, 'var3': 'ZZ'}]
...: )
In [3]: df
Out[3]:
var1 var2 var3
0 a,b,c 1 XX
1 d,e,f,x,y 2 ZZ
In [4]: (df.set_index(df.columns.drop('var1',1).tolist())
...: .var1.str.split(',', expand=True)
...: .stack()
...: .reset_index()
...: .rename(columns={0:'var1'})
...: .loc[:, df.columns]
...: )
Out[4]:
var1 var2 var3
0 a 1 XX
1 b 1 XX
2 c 1 XX
3 d 2 ZZ
4 e 2 ZZ
5 f 2 ZZ
6 x 2 ZZ
7 y 2 ZZ
답변 2
파이썬의 데이터 분석 라이브러리 판다스(Pandas)는 막강한 기능을 지닌 데이터 조작 도구입니다. 그 중에서도 데이터프레임(DataFrame)은 엑셀과 같은 테이블 형태의 데이터를 다루기에 최적화된 자료구조입니다. 그러나 때로는 데이터프레임 내의 텍스트 데이터가 하나의 열(column)에 모두 담겨 있어서, 분석에 어려움을 겪을 수 있습니다. 예를 들어, 여러 개의 태그가 쉼표로 구분되어 있는 경우가 그렇습니다.이 때, 판다스의 문자열(string) 메서드인 split을 활용하면, 하나의 문자열을 분리하여 여러 개의 행(row)으로 나눌 수 있습니다. 이를 통해 데이터프레임의 텍스트 데이터를 분석하기 쉽게 만들 수 있습니다.
먼저, split 메서드를 사용하는 방법은 간단합니다. 다음과 같이 문자열이 담겨 있는 열(column)과 구분자(separator)를 지정해주면 됩니다.
``` python
import pandas as pd
df = pd.DataFrame({'tags': ['python, pandas, data analysis',
'data science, machine learning']})
df['tags'] = df['tags'].str.split(', ')
print(df)
```
위 코드에서는 두 개의 문자열이 담겨 있는 'tags' 열을 선택하고, 쉼표와 공백을 기준으로 분리하여 새로운 열로 지정해줍니다. 결과는 다음과 같습니다.
```
tags
0 [python, pandas, data analysis]
1 [data science, machine learning]
```
이제 'tags' 열의 하나의 문자열이 하나의 행으로 나누어진 것을 확인할 수 있습니다. 이를 활용하여, 특정 태그를 가지고 있는 데이터만 추출하거나, 각 태그가 몇 번 등장하는지 확인하는 작업 등을 할 수 있습니다.
반면, split 메서드를 사용할 때 주의할 점도 있습니다. 만약 분리된 결과가 다른 열(column)의 데이터 수와 일치하지 않는다면, 에러가 발생할 수 있습니다. 이 경우에는 문자열을 적절히 처리하여 분리할 수 있는 방법을 찾아 사용해야 합니다.
결론적으로, split 메서드를 활용하여 데이터프레임의 문자열 데이터를 간편하게 분리하고, 분석에 활용할 수 있습니다.하지만, 데이터의 유형과 분석에 필요한 데이터의 형태에 따라 적절한 방법을 선택해야 한다는 점을 잊지 않아야 합니다.