[PYTHON] pandas DataFrame에서 열을 중첩 제거하려면 어떻게합니까?
PYTHONpandas DataFrame에서 열을 중첩 제거하려면 어떻게합니까?
다음 열의 한 개체 (목록 형식 셀) DataFrame 있어요 :
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2]]})
df
Out[458]:
A B
0 1 [1, 2]
1 2 [1, 2]
내 예상 출력 :
A B
0 1 1
1 1 2
3 2 1
4 2 2
이를 위해 무엇을해야합니까?
해결법
-
==============================
1.R과 python을 모두 가지고 있고이 사이트에서 1 년을 보냈던 사용자로서 저는 이런 유형의 질문을 두 번 보았습니다.
R과 python을 모두 가지고 있고이 사이트에서 1 년을 보냈던 사용자로서 저는 이런 유형의 질문을 두 번 보았습니다.
R에서 그들은 unest라고 불리는 패키지 tidyr의 빌드 인 함수를 가지고 있기 때문에, 그러나 Python (pandas)에서는이 유형의 질문을위한 빌드 인 함수가 없습니다.
개체 열 형식은 항상 데이터를 판다의 기능으로 변환하기 어렵게 만듭니다. 이와 같은 데이터를 받았을 때 가장 먼저 떠오르는 것은 열을 "평평하게"또는 부식하지 않는 것입니다.
방법 1 apply + pd.Series (권장하지 않는 성능 측면에서 이해하기 쉽습니다.)
df.set_index('A').B.apply(pd.Series).stack().reset_index(level=0).rename(columns={0:'B'}) Out[463]: A B 0 1 1 1 1 2 0 2 1 1 2 2
방법 2 DataFrame 생성자를 사용하여 반복을 사용하여 데이터 프레임을 다시 만듭니다 (성능이 좋음, 여러 열이 좋지 않음).
df=pd.DataFrame({'A':df.A.repeat(df.B.str.len()),'B':np.concatenate(df.B.values)}) df Out[465]: A B 0 1 1 0 1 2 1 2 1 1 2 2
방법 2.1 예를 들어 A 이외에 우리는 A.1 ..... A.n을 가지고 있습니다. 위의 방법 (방법 2)을 여전히 사용한다면 우리는 하나씩 열을 다시 만들 수 없습니다.
해결책 : 단일 열을 '제거'한 후 인덱스에 조인하거나 병합하십시오.
s=pd.DataFrame({'B':np.concatenate(df.B.values)},index=df.index.repeat(df.B.str.len())) s.join(df.drop('B',1),how='left') Out[477]: B A 0 1 1 0 2 1 1 1 2 1 2 2
이전과 완전히 똑같은 열 순서가 필요한 경우 끝에 색인을 추가하십시오.
s.join(df.drop('B',1),how='left').reindex(columns=df.columns)
방법 3 목록 다시 만들기
pd.DataFrame([[x] + [z] for x, y in df.values for z in y],columns=df.columns) Out[488]: A B 0 1 1 1 1 2 2 2 1 3 2 2
세 개 이상의 열
s=pd.DataFrame([[x] + [z] for x, y in zip(df.index,df.B) for z in y]) s.merge(df,left_on=0,right_index=True) Out[491]: 0 1 A B 0 0 1 1 [1, 2] 1 0 2 1 [1, 2] 2 1 1 2 [1, 2] 3 1 2 2 [1, 2]
다시 색인 또는 loc을 사용하는 방법 4
df.reindex(df.index.repeat(df.B.str.len())).assign(B=np.concatenate(df.B.values)) Out[554]: A B 0 1 1 0 1 2 1 2 1 1 2 2 #df.loc[df.index.repeat(df.B.str.len())].assign(B=np.concatenate(df.B.values))
목록에 고유 한 값만 포함 된 경우 방법 5
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[3,4]]}) from collections import ChainMap d = dict(ChainMap(*map(dict.fromkeys, df['B'], df['A']))) pd.DataFrame(list(d.items()),columns=df.columns[::-1]) Out[574]: B A 0 1 1 1 2 1 2 3 2 3 4 2
특수 케이스에는 두 개의 열 유형 객체가 있습니다.
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[3,4]],'C':[[1,2],[3,4]]}) df Out[592]: A B C 0 1 [1, 2] [1, 2] 1 2 [3, 4] [3, 4]
자기 방어 기능
def unnesting(df, explode): idx=df.index.repeat(df[explode[0]].str.len()) df1=pd.concat([pd.DataFrame({x:np.concatenate(df[x].values)} )for x in explode],axis=1) df1.index=idx return df1.join(df.drop(explode,1),how='left') unnesting(df,['B','C']) Out[609]: B C A 0 1 1 1 0 2 2 1 1 3 3 2 1 4 4 2
요약 :
나는 질문 의이 유형에 대한 팬더와 파이썬 함수를 사용하고 있습니다, 당신이 위의 솔루션의 속도에 대해 걱정한다면, 그는 numpy를 사용하고 numpy를 사용하는 것이 빠르기 때문에 user3483203의 대답을 확인할 수 있습니다. 속도가 문제에 영향을 준다면 Cpython과 numba를 추천합니다.
-
==============================
2.옵션 1
옵션 1
다른 열의 모든 하위 목록이 동일한 길이이면 numpy는 여기에서 효율적인 옵션이 될 수 있습니다.
vals = np.array(df.B.values.tolist()) a = np.repeat(df.A, vals.shape[1]) pd.DataFrame(np.column_stack((a, vals.ravel())), columns=df.columns)
A B 0 1 1 1 1 2 2 2 1 3 2 2
옵션 2
하위 목록의 길이가 다른 경우 추가 단계가 필요합니다.
vals = df.B.values.tolist() rs = [len(r) for r in vals] a = np.repeat(df.A, rs) pd.DataFrame(np.column_stack((a, np.concatenate(vals))), columns=df.columns)
A B 0 1 1 1 1 2 2 2 1 3 2 2
옵션 3
나는 N 컬럼과 M 컬럼을 평평하게하기 위해 이것을 일반화하는 데에 총을 썼다. 나중에 더 효율적으로 만들 것이다.
df = pd.DataFrame({'A': [1,2,3], 'B': [[1,2], [1,2,3], [1]], 'C': [[1,2,3], [1,2], [1,2]], 'D': ['A', 'B', 'C']})
A B C D 0 1 [1, 2] [1, 2, 3] A 1 2 [1, 2, 3] [1, 2] B 2 3 [1] [1, 2] C
def unnest(df, tile, explode): vals = df[explode].sum(1) rs = [len(r) for r in vals] a = np.repeat(df[tile].values, rs, axis=0) b = np.concatenate(vals.values) d = np.column_stack((a, b)) return pd.DataFrame(d, columns = tile + ['_'.join(explode)]) unnest(df, ['A', 'D'], ['B', 'C'])
A D B_C 0 1 A 1 1 1 A 2 2 1 A 1 3 1 A 2 4 1 A 3 5 2 B 1 6 2 B 2 7 2 B 3 8 2 B 1 9 2 B 2 10 3 C 1 11 3 C 1 12 3 C 2
기능들
def wen1(df): return df.set_index('A').B.apply(pd.Series).stack().reset_index(level=0).rename(columns={0: 'B'}) def wen2(df): return pd.DataFrame({'A':df.A.repeat(df.B.str.len()),'B':np.concatenate(df.B.values)}) def wen3(df): s = pd.DataFrame({'B': np.concatenate(df.B.values)}, index=df.index.repeat(df.B.str.len())) return s.join(df.drop('B', 1), how='left') def wen4(df): return pd.DataFrame([[x] + [z] for x, y in df.values for z in y],columns=df.columns) def chris1(df): vals = np.array(df.B.values.tolist()) a = np.repeat(df.A, vals.shape[1]) return pd.DataFrame(np.column_stack((a, vals.ravel())), columns=df.columns) def chris2(df): vals = df.B.values.tolist() rs = [len(r) for r in vals] a = np.repeat(df.A.values, rs) return pd.DataFrame(np.column_stack((a, np.concatenate(vals))), columns=df.columns)
타이밍
import pandas as pd import matplotlib.pyplot as plt import numpy as np from timeit import timeit res = pd.DataFrame( index=['wen1', 'wen2', 'wen3', 'wen4', 'chris1', 'chris2'], columns=[10, 50, 100, 500, 1000, 5000, 10000], dtype=float ) for f in res.index: for c in res.columns: df = pd.DataFrame({'A': [1, 2], 'B': [[1, 2], [1, 2]]}) df = pd.concat([df]*c) stmt = '{}(df)'.format(f) setp = 'from __main__ import df, {}'.format(f) res.at[f, c] = timeit(stmt, setp, number=50) ax = res.div(res.min()).T.plot(loglog=True) ax.set_xlabel("N") ax.set_ylabel("time (relative)")
공연
-
==============================
3.꽤 추천하지 않는 것 (적어도이 경우 작동) :
꽤 추천하지 않는 것 (적어도이 경우 작동) :
df=pd.concat([df]*2).sort_index() it=iter(df['B'].tolist()[0]+df['B'].tolist()[0]) df['B']=df['B'].apply(lambda x:next(it))
concat + sort_index + iter + apply + next.
지금:
print(df)
:
A B 0 1 1 0 1 2 1 2 1 1 2 2
색인에 관심이있는 경우 :
df=df.reset_index(drop=True)
지금:
print(df)
:
A B 0 1 1 1 1 2 2 2 1 3 2 2
from https://stackoverflow.com/questions/53218931/how-do-i-unnest-a-column-in-a-pandas-dataframe by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 어떻게하면 x 개의 원소마다리스트를 나누고 그 원소 x 개의 원소를 새로운리스트에 추가 할 수 있을까요? (0) | 2018.11.25 |
---|---|
[PYTHON] 단어 - 단어 동시 발생 매트릭스 (0) | 2018.11.25 |
[PYTHON] BigQuery Python CLI에 GOOGLE_APPLICATION_CREDENTIALS 설정하기 (0) | 2018.11.24 |
[PYTHON] 'stdin'을 파이썬의 다른 프로세스에 인수로 전달하는 방법이 있습니까? (0) | 2018.11.24 |
[PYTHON] PyCharm에서 Python 2 코드를 3으로 변환 (0) | 2018.11.24 |