판다 열을 여러 열로 분할
Panda DataFrame에는 다음과 같은 컬럼이 있습니다.
import pandas as pd
df = pd.DataFrame({"teams": [["SF", "NYG"] for _ in range(7)]})
teams
0 [SF, NYG]
1 [SF, NYG]
2 [SF, NYG]
3 [SF, NYG]
4 [SF, NYG]
5 [SF, NYG]
6 [SF, NYG]
이 목록 열을 두 열로 분할하려면 어떻게 해야 합니까?
원하는 결과:
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
를 사용할 수 있습니다.DataFrame
을 가진 건설업자lists
작성자:
import pandas as pd
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
print (df2)
teams
0 [SF, NYG]
1 [SF, NYG]
2 [SF, NYG]
3 [SF, NYG]
4 [SF, NYG]
5 [SF, NYG]
6 [SF, NYG]
df2[['team1','team2']] = pd.DataFrame(df2.teams.tolist(), index= df2.index)
print (df2)
teams team1 team2
0 [SF, NYG] SF NYG
1 [SF, NYG] SF NYG
2 [SF, NYG] SF NYG
3 [SF, NYG] SF NYG
4 [SF, NYG] SF NYG
5 [SF, NYG] SF NYG
6 [SF, NYG] SF NYG
그리고 새로운 것을 위해DataFrame
:
df3 = pd.DataFrame(df2['teams'].to_list(), columns=['team1','team2'])
print (df3)
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
솔루션:apply(pd.Series)
매우 느립니다.
#7k rows
df2 = pd.concat([df2]*1000).reset_index(drop=True)
In [121]: %timeit df2['teams'].apply(pd.Series)
1.79 s ± 52.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [122]: %timeit pd.DataFrame(df2['teams'].to_list(), columns=['team1','team2'])
1.63 ms ± 54.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
훨씬 심플한 솔루션:
pd.DataFrame(df2["teams"].to_list(), columns=['team1', 'team2'])
수율,
team1 team2
-------------
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
7 SF NYG
리스트가 아닌 구분 문자열 열을 분할하는 경우에도 마찬가지로 다음을 수행할 수 있습니다.
pd.DataFrame(df["teams"].str.split('<delim>', expand=True).values,
columns=['team1', 'team2'])
이 솔루션은 다음 인덱스를 유지합니다.df2
Data Frame을 사용하는 다른 솔루션과는 달리tolist()
:
df3 = df2.teams.apply(pd.Series)
df3.columns = ['team1', 'team2']
결과는 다음과 같습니다.
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
제안된 솔루션과는 달리 구문적으로 더 단순하고 기억하기 쉬운 방법이 있는 것 같습니다.데이터 프레임 df에서는 컬럼을 '메타'라고 부릅니다.
df2 = pd.DataFrame(df['meta'].str.split().values.tolist())
지금까지의 솔루션은, 지금까지의 솔루션으로는 효과가 없었습니다.nan
나의 관찰.dataframe
저 같은 경우에는df2[['team1','team2']] = pd.DataFrame(df2.teams.values.tolist(), index= df2.index)
수율:
object of type 'float' has no len()
나는 이것을 목록 이해로 푼다.다음으로 재현 가능한 예를 제시하겠습니다.
import pandas as pd
import numpy as np
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
df2.loc[2,'teams'] = np.nan
df2.loc[4,'teams'] = np.nan
df2
출력:
teams
0 [SF, NYG]
1 [SF, NYG]
2 NaN
3 [SF, NYG]
4 NaN
5 [SF, NYG]
6 [SF, NYG]
df2['team1']=np.nan
df2['team2']=np.nan
목록 이해로 풀면,
for i in [0,1]:
df2['team{}'.format(str(i+1))]=[k[i] if isinstance(k,list) else k for k in df2['teams']]
df2
수율:
teams team1 team2
0 [SF, NYG] SF NYG
1 [SF, NYG] SF NYG
2 NaN NaN NaN
3 [SF, NYG] SF NYG
4 NaN NaN NaN
5 [SF, NYG] SF NYG
6 [SF, NYG] SF NYG
리스트 이해
목록 이해 기능을 갖춘 심플한 구현(즐겨찾기)
df = pd.DataFrame([pd.Series(x) for x in df.teams])
df.columns = ['team_{}'.format(x+1) for x in df.columns]
출력 타이밍:
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 2.71 ms
출력:
team_1 team_2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
나는 좀 더 효율적이고 피톤적인 방법을 추천하고 싶다.
먼저 Data Frame을 원본 게시물로 정의합니다.
df = pd.DataFrame({"teams": [["SF", "NYG"] for _ in range(7)]})
솔루션:
%%timeit
df['team1'], df['team2'] = zip(*list(df['teams'].values))
>> 761 µs ± 8.35 µs per loop
이에 비해 가장 높은 평가를 받은 솔루션은 다음과 같습니다.
%%timeit
df[['team1','team2']] = pd.DataFrame(df.teams.tolist(), index=df.index)
df = pd.DataFrame(df['teams'].to_list(), columns=['team1','team2'])
>> 1.31 ms ± 11.2 µs per loop
이 솔루션은 시간을 40% 절약하고 훨씬 단축합니다.기억해야 할 것은 2차원 리스트를 압축 해제하고 재구성하는 방법뿐입니다.zip(*list)
.
를 사용하는 다른 솔루션은 다음과 같습니다.
>>> from operator import itemgetter
>>> df['teams'].transform({'item1': itemgetter(0), 'item2': itemgetter(1)})
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
물론 다음과 같이 일반화할 수 있습니다.
>>> indices = range(len(df['teams'][0]))
>>> df['teams'].transform({f'team{i+1}': itemgetter(i) for i in indices})
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
이 접근방식은 원하는 지수를 추출하는 추가적인 이점이 있다.
>>> df
teams
0 [SF, NYG, XYZ, ABC]
1 [SF, NYG, XYZ, ABC]
2 [SF, NYG, XYZ, ABC]
3 [SF, NYG, XYZ, ABC]
4 [SF, NYG, XYZ, ABC]
5 [SF, NYG, XYZ, ABC]
6 [SF, NYG, XYZ, ABC]
>>> indices = [0, 2]
>>> df['teams'].transform({f'team{i+1}': itemgetter(i) for i in indices})
team1 team3
0 SF XYZ
1 SF XYZ
2 SF XYZ
3 SF XYZ
4 SF XYZ
5 SF XYZ
6 SF XYZ
이전 답변을 바탕으로 df2.teams.apply(pd)와 동일한 결과를 반환하는 다른 솔루션을 소개합니다.Series)는 실행 시간이 훨씬 더 빠릅니다.
pd.DataFrame([{x: y for x, y in enumerate(item)} for item in df2['teams'].values.tolist()], index=df2.index)
타이밍:
In [1]:
import pandas as pd
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
df2 = pd.concat([df2]*1000).reset_index(drop=True)
In [2]: %timeit df2['teams'].apply(pd.Series)
8.27 s ± 2.73 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [3]: %timeit pd.DataFrame([{x: y for x, y in enumerate(item)} for item in df2['teams'].values.tolist()], index=df2.index)
35.4 ms ± 5.22 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
두 번의 적용을 사용하여 df에 새 열 'team1'과 'team2'를 만들 수 있습니다.
df = pd.DataFrame({"teams": [["SF", "NYG"] for _ in range(7)]})
df["team1"]=df['teams'].apply(lambda x: x[0] )
df["team2"]=df['teams'].apply(lambda x: x[1] )
df
언급URL : https://stackoverflow.com/questions/35491274/split-a-pandas-column-of-lists-into-multiple-columns
'programing' 카테고리의 다른 글
태그를 생략하고 태그의 내용을 렌더링하는 사용자 지정 Vue 지시문을 사용하시겠습니까? (0) | 2022.10.23 |
---|---|
JavaScript에 RegExp.escape 함수가 있나요? (0) | 2022.10.23 |
setState 업데이트가 완료된 후 함수를 실행할 수 있습니까? (0) | 2022.10.22 |
MariaDB - 최대 BLOB 사이즈는? (0) | 2022.10.22 |
mysql 비밀번호 검증을 해제하려면 어떻게 해야 하나요? (0) | 2022.10.22 |