programing

판다 열을 여러 열로 분할

randomtip 2022. 10. 22. 09:56
반응형

판다 열을 여러 열로 분할

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'])

이 솔루션은 다음 인덱스를 유지합니다.df2Data 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

반응형