판다 데이터 프레임에서 튜플 열을 분할하려면 어떻게 해야 합니까?
저는 Pandas 데이터 프레임을 가지고 있습니다(이것은 작은 조각에 불과합니다.
>>> d1
y norm test y norm train len(y_train) len(y_test) \
0 64.904368 116.151232 1645 549
1 70.852681 112.639876 1645 549
SVR RBF \
0 (35.652207342877873, 22.95533537448393)
1 (39.563683797747622, 27.382483096332511)
LCV \
0 (19.365430594452338, 13.880062435173587)
1 (19.099614489458364, 14.018867136617146)
RIDGE CV \
0 (4.2907610988480362, 12.416745648065584)
1 (4.18864306788194, 12.980833914392477)
RF \
0 (9.9484841581029428, 16.46902345373697)
1 (10.139848213735391, 16.282141345406522)
GB \
0 (0.012816232716538605, 15.950164822266007)
1 (0.012814519804493328, 15.305745202851712)
ET DATA
0 (0.00034337162272515505, 16.284800366214057) j2m
1 (0.00024811554516431878, 15.556506191784194) j2m
>>>
튜플이 들어 있는 모든 열을 분할하고 싶습니다.예를 들어 열을 바꾸려고 합니다.LCV
종대와 함께LCV-a
그리고.LCV-b
.
내가 어떻게 그럴 수 있을까?
다음을 수행하여 이 작업을 수행하면pd.DataFrame(col.tolist())
그 열에:
In [2]: df = pd.DataFrame({'a':[1,2], 'b':[(1,2), (3,4)]})
In [3]: df
Out[3]:
a b
0 1 (1, 2)
1 2 (3, 4)
In [4]: df['b'].tolist()
Out[4]: [(1, 2), (3, 4)]
In [5]: pd.DataFrame(df['b'].tolist(), index=df.index)
Out[5]:
0 1
0 1 2
1 3 4
In [6]: df[['b1', 'b2']] = pd.DataFrame(df['b'].tolist(), index=df.index)
In [7]: df
Out[7]:
a b b1 b2
0 1 (1, 2) 1 2
1 2 (3, 4) 3 4
참고: 이전 버전에서는 이 답변을 사용할 것을 권장합니다.df['b'].apply(pd.Series)
대신에pd.DataFrame(df['b'].tolist(), index=df.index)
이 기능도 작동합니다(데이터 프레임의 행으로 표시되는 각 튜플의 Series를 만들기 때문에). 하지만 속도가 느립니다. / 메모리를 더 많이 사용합니다.tolist
(덴프롬파 덕분에) 여기 있는 다른 답변에 의해 언급된 버전.
그str
사용 가능한 접근자pandas.Series
의 물건.dtype == object
사실은 참회할 만한 일입니다.
가정:pandas.DataFrame
df
:
df = pd.DataFrame(dict(col=[*zip('abcdefghij', range(10, 101, 10))]))
df
col
0 (a, 10)
1 (b, 20)
2 (c, 30)
3 (d, 40)
4 (e, 50)
5 (f, 60)
6 (g, 70)
7 (h, 80)
8 (i, 90)
9 (j, 100)
반복 가능한지 테스트할 수 있습니다.
from collections import Iterable
isinstance(df.col.str, Iterable)
True
그런 다음 다른 반복 가능한 작업처럼 이 작업을 통해 할당할 수 있습니다.
var0, var1 = 'xy'
print(var0, var1)
x y
가장 간단한 해결책
따라서 한 줄로 두 열을 모두 할당할 수 있습니다.
df['a'], df['b'] = df.col.str
df
col a b
0 (a, 10) a 10
1 (b, 20) b 20
2 (c, 30) c 30
3 (d, 40) d 40
4 (e, 50) e 50
5 (f, 60) f 60
6 (g, 70) g 70
7 (h, 80) h 80
8 (i, 90) i 90
9 (j, 100) j 100
더 빠른 솔루션
조금만 더 복잡하면, 우리는 사용할 수 있습니다.zip
유사한 반복 가능한 항목 만들기
df['c'], df['d'] = zip(*df.col)
df
col a b c d
0 (a, 10) a 10 a 10
1 (b, 20) b 20 b 20
2 (c, 30) c 30 c 30
3 (d, 40) d 40 d 40
4 (e, 50) e 50 e 50
5 (f, 60) f 60 f 60
6 (g, 70) g 70 g 70
7 (h, 80) h 80 h 80
8 (i, 90) i 90 i 90
9 (j, 100) j 100 j 100
인라인
즉, 기존의 것을 변형시키지 않습니다.df
.
이는 다음과 같은 이유로 작동합니다.assign
키워드 인수를 사용합니다. 여기서 키워드는 새(또는 기존) 열 이름이고 값은 새 열의 값이 됩니다.당신은 사전을 사용하고 그것을 풀 수 있습니다.**
키워드 인수 역할을 하도록 합니다.
그래서 이것은 새로운 열을 할당하는 영리한 방법입니다.'g'
그것이 첫 번째 항목입니다.df.col.str
참을 수 있는'h'
그것은 두 번째 항목입니다.df.col.str
반복 가능:
df.assign(**dict(zip('gh', df.col.str)))
col g h
0 (a, 10) a 10
1 (b, 20) b 20
2 (c, 30) c 30
3 (d, 40) d 40
4 (e, 50) e 50
5 (f, 60) f 60
6 (g, 70) g 70
7 (h, 80) h 80
8 (i, 90) i 90
9 (j, 100) j 100
나의 버전의list
접근
최신 목록 이해 및 변수 압축 풀기 기능을 제공합니다.참고: 인라인 사용join
df.join(pd.DataFrame([*df.col], df.index, [*'ef']))
col g h
0 (a, 10) a 10
1 (b, 20) b 20
2 (c, 30) c 30
3 (d, 40) d 40
4 (e, 50) e 50
5 (f, 60) f 60
6 (g, 70) g 70
7 (h, 80) h 80
8 (i, 90) i 90
9 (j, 100) j 100
돌연변이 버전은 다음과 같습니다.
df[['e', 'f']] = pd.DataFrame([*df.col], df.index)
나이브 타임 테스트
Short DataFrame위에 정의된 것을 사용합니다.
%timeit df.assign(**dict(zip('gh', df.col.str)))
%timeit df.assign(**dict(zip('gh', zip(*df.col))))
%timeit df.join(pd.DataFrame([*df.col], df.index, [*'gh']))
1.16 ms ± 21.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
635 µs ± 18.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
795 µs ± 42.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Long DataFrame
10^3배 더 큰
df = pd.concat([df] * 1000, ignore_index=True)
%timeit df.assign(**dict(zip('gh', df.col.str)))
%timeit df.assign(**dict(zip('gh', zip(*df.col))))
%timeit df.join(pd.DataFrame([*df.col], df.index, [*'gh']))
11.4 ms ± 1.53 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.1 ms ± 41.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.33 ms ± 35.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
훨씬 더 큰 데이터셋에서 다음과 같은 이점이 있습니다..apply()
보다 몇 자릿수 느림pd.DataFrame(df['b'].values.tolist(), index=df.index)
.
이 성능 문제는 GitHub에서 종결되었지만, 저는 이 결정에 동의하지 않습니다.
성능 문제 - PD와 함께 적용합니다.시리즈 대 튜플 #11615
더 간단한 방법은 다음과 같습니다.
>>> import pandas as pd
>>> df = pd.DataFrame({'a':[1,2], 'b':[(1,2), (3,4)]})
>>> df
a b
0 1 (1, 2)
1 2 (3, 4)
>>> df['b_a'] = df['b'].str[0]
>>> df['b_b'] = df['b'].str[1]
>>> df
a b b_a b_b
0 1 (1, 2) 1 2
1 2 (3, 4) 3 4
두 번째 해결책에 대한 경고,
pd.DataFrame(df['b'].values.tolist())
즉, 명시적으로 인덱스를 폐기하고 기본 순차 인덱스를 추가합니다. 반면에 허용된 답변은
apply(pd.Series)
적용 결과가 행 인덱스를 유지하기 때문에 그렇지 않습니다.순서는 처음에는 원래 배열에서 유지되지만 판다는 두 데이터 프레임의 인덱스를 일치시키려고 합니다.
이는 행을 숫자로 인덱싱된 배열로 설정하려는 경우 매우 중요할 수 있으며 Pandas는 새 배열의 인덱스를 이전 배열과 자동으로 일치시키려고 시도하여 순서가 약간 왜곡됩니다.
더 나은 하이브리드 솔루션은 원래 데이터 프레임의 인덱스를 새로운 데이터 프레임으로 설정하는 것입니다.
pd.DataFrame(df['b'].values.tolist(), index=df.index)
두 번째 방법을 사용하는 속도를 유지하는 동시에 결과에 대한 순서와 인덱싱을 유지합니다.
panda.Series.str.extract도 옵션입니다. https://opendataportal-lasvegas.opendata.arcgis.com/datasets/restaurant-inspections-open-data/explore 의 데이터를 사용하십시오.
import pandas as pd
df = pd.read_csv('raw_data.csv', low_memory=False)
df[['latitude', 'longitude']] = df['Location_1'].str.extract(pat = '(-?\d+\.\d+),\s*(-?\d+\.\d+)')
df.to_csv('result.csv')
언급URL : https://stackoverflow.com/questions/29550414/how-can-i-split-a-column-of-tuples-in-a-pandas-dataframe
'programing' 카테고리의 다른 글
안드로이드에서 투명한 활동을 만들려면 어떻게 해야 합니까? (0) | 2023.06.30 |
---|---|
커밋 타임스탬프를 변경하지 않고 gitrebase (0) | 2023.06.30 |
단일 개정판의 git 로그 (0) | 2023.06.30 |
c/c++ 컴파일러는 2의 거듭제곱 값에 의한 상수 분할을 시프트로 최적화합니까? (0) | 2023.06.30 |
일치하는 호스트 키 유형을 찾을 수 없습니다.그들의 제안: ssh-rsa. (0) | 2023.06.30 |