[PYTHON] 판다에서 인형으로 범주 형 변수 재구성
PYTHON판다에서 인형으로 범주 형 변수 재구성
pd.get_dummies를 사용하면 범주 형 변수를 더미 변수로 변환 할 수 있습니다. 범주 형 변수를 재구성하는 것이 사소한 것 외에도,이를 수행하는 것이 바람직한 / 빠른 방법이 있습니까?
해결법
-
==============================
1.
In [46]: s = Series(list('aaabbbccddefgh')).astype('category') In [47]: s Out[47]: 0 a 1 a 2 a 3 b 4 b 5 b 6 c 7 c 8 d 9 d 10 e 11 f 12 g 13 h dtype: category Categories (8, object): [a < b < c < d < e < f < g < h] In [48]: df = pd.get_dummies(s) In [49]: df Out[49]: a b c d e f g h 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 3 0 1 0 0 0 0 0 0 4 0 1 0 0 0 0 0 0 5 0 1 0 0 0 0 0 0 6 0 0 1 0 0 0 0 0 7 0 0 1 0 0 0 0 0 8 0 0 0 1 0 0 0 0 9 0 0 0 1 0 0 0 0 10 0 0 0 0 1 0 0 0 11 0 0 0 0 0 1 0 0 12 0 0 0 0 0 0 1 0 13 0 0 0 0 0 0 0 1 In [50]: x = df.stack() # I don't think you actually need to specify ALL of the categories here, as by definition # they are in the dummy matrix to start (and hence the column index) In [51]: Series(pd.Categorical(x[x!=0].index.get_level_values(1))) Out[51]: 0 a 1 a 2 a 3 b 4 b 5 b 6 c 7 c 8 d 9 d 10 e 11 f 12 g 13 h Name: level_1, dtype: category Categories (8, object): [a < b < c < d < e < f < g < h]
그래서 자연스러운 행동 인 것처럼 우리가 '할'기능이 필요하다고 생각합니다. 어쩌면 get_categories (), 여기를 보아라.
-
==============================
2.몇 년이 지났습니다.이 질문은 원래 질문을 받았을 때 팬더 툴킷에 없었을 수도 있지만,이 접근법은 나에게 조금 더 쉬워 보입니다. idxmax는 가장 큰 요소 (즉 1이있는 요소)에 해당하는 인덱스를 반환합니다. 우리는 1이 발생하는 열 이름을 원하기 때문에 axis = 1을 수행합니다.
몇 년이 지났습니다.이 질문은 원래 질문을 받았을 때 팬더 툴킷에 없었을 수도 있지만,이 접근법은 나에게 조금 더 쉬워 보입니다. idxmax는 가장 큰 요소 (즉 1이있는 요소)에 해당하는 인덱스를 반환합니다. 우리는 1이 발생하는 열 이름을 원하기 때문에 axis = 1을 수행합니다.
편집 : 나는 그것을 단순한 문자열 대신에 범주화하지 않았지만, @ Jeff가 pd.Categorical (그리고 pd.Series, 원할 경우)으로 감싸는 것과 같은 방식으로 그렇게 할 수있다.
In [1]: import pandas as pd In [2]: s = pd.Series(['a', 'b', 'a', 'c']) In [3]: s Out[3]: 0 a 1 b 2 a 3 c dtype: object In [4]: dummies = pd.get_dummies(s) In [5]: dummies Out[5]: a b c 0 1 0 0 1 0 1 0 2 1 0 0 3 0 0 1 In [6]: s2 = dummies.idxmax(axis=1) In [7]: s2 Out[7]: 0 a 1 b 2 a 3 c dtype: object In [8]: (s2 == s).all() Out[8]: True
@ piRSquared 님의 의견에 대한 응답으로 편집 : 이 솔루션은 실제로 행당 1 개가 있다고 가정합니다. 나는 이것이 일반적으로 하나의 형식이라고 생각한다. pd_get_dummies는 drop_first = True 또는 NaN 값이 있고 dummy_na = False (기본값) (누락 된 경우)가있는 경우 모두 0 인 행을 반환 할 수 있습니다. 모든 0 행은 첫 번째 열 (예 : 위의 예에서)에 명명 된 변수의 인스턴스 인 것처럼 처리됩니다.
drop_first = True 인 경우, "첫 번째"변수의 이름이 무엇인지 인형 데이터 프레임만으로 알 수있는 방법이 없기 때문에 추가 정보를 유지하지 않으면 작업이 반전되지 않습니다. drop_first = False (기본값)로 두는 것이 좋습니다.
dummy_na = False가 기본값이기 때문에 문제가 발생할 수 있습니다. 이 솔루션을 사용하여 "dummification"을 반전시키고 데이터에 NaN이 포함되어 있다면 pd.get_dummies를 호출 할 때 dummy_na = True를 설정하십시오. dummy_na = True로 설정하면 해당 열이 모두 0 인 경우에도 항상 "nan"열이 추가되므로 실제로 NaN이 없으면 설정하지 않는 것이 좋습니다. 좋은 방법은 더미 세트 = pd.get_dummies (series, dummy_na = series.isnull (). any ())를 설정하는 것입니다. 또한 좋은 점은 idxmax 솔루션이 NaN을 정확하게 재생성한다는 것입니다 ( "nan"이라고하는 문자열이 아님).
또한 drop_first = True 및 dummy_na = False를 설정하면 NaN이 첫 번째 변수의 인스턴스와 구별 할 수 없으므로 데이터 세트에 NaN 값이 포함될 수있는 경우에는이 설정을 사용하지 않는 것이 좋습니다.
-
==============================
3.이것은 꽤 늦은 대답이지만, 당신이 그것을 할 수있는 빠른 방법을 요구하기 때문에, 나는 당신이 가장 뛰어난 전략을 찾고 있다고 가정합니다. 큰 데이터 프레임 (예 : 10000 행)에서는 idxmax 또는 get_level_values 대신 np.where를 사용하여 매우 빠른 속도 향상을 얻을 수 있으며 동일한 결과를 얻을 수 있습니다. 아이디어는 더미 데이터 프레임이 0이 아닌 열 이름을 인덱싱하는 것입니다.
이것은 꽤 늦은 대답이지만, 당신이 그것을 할 수있는 빠른 방법을 요구하기 때문에, 나는 당신이 가장 뛰어난 전략을 찾고 있다고 가정합니다. 큰 데이터 프레임 (예 : 10000 행)에서는 idxmax 또는 get_level_values 대신 np.where를 사용하여 매우 빠른 속도 향상을 얻을 수 있으며 동일한 결과를 얻을 수 있습니다. 아이디어는 더미 데이터 프레임이 0이 아닌 열 이름을 인덱싱하는 것입니다.
@ Nathan과 동일한 샘플 데이터 사용 :
>>> dummies a b c 0 1 0 0 1 0 1 0 2 1 0 0 3 0 0 1 s2 = pd.Series(dummies.columns[np.where(dummies!=0)[1]]) >>> s2 0 a 1 b 2 a 3 c dtype: object
작은 더미 데이터 프레임에서는 성능에 큰 차이가 없습니다. 그러나 대형 시리즈에서이 문제를 해결하기위한 다양한 전략을 테스트하십시오.
s = pd.Series(np.random.choice(['a','b','c'], 10000)) dummies = pd.get_dummies(s) def np_method(dummies=dummies): return pd.Series(dummies.columns[np.where(dummies!=0)[1]]) def idx_max_method(dummies=dummies): return dummies.idxmax(axis=1) def get_level_values_method(dummies=dummies): x = dummies.stack() return pd.Series(pd.Categorical(x[x!=0].index.get_level_values(1))) def dot_method(dummies=dummies): return dummies.dot(dummies.columns) import timeit # Time each method, 1000 iterations each: >>> timeit.timeit(np_method, number=1000) 1.0491090340074152 >>> timeit.timeit(idx_max_method, number=1000) 12.119140846014488 >>> timeit.timeit(get_level_values_method, number=1000) 4.109266621991992 >>> timeit.timeit(dot_method, number=1000) 1.6741622970002936
np.where 메서드는 idxmax 메서드보다 11.5 배 빠른 get_level_values 메서드보다 약 4 배 빠릅니다! 유사한 질문에 대한이 대답에서 개략적으로 설명한 .dot () 메서드를 깨는 것입니다 (하지만 약간 만).
그들은 모두 동일한 결과를 반환합니다.
>>> (get_level_values_method() == np_method()).all() True >>> (idx_max_method() == np_method()).all() True
-
==============================
4.@ Jeff의 설정 사용하기
@ Jeff의 설정 사용하기
s = Series(list('aaabbbccddefgh')).astype('category') df = pd.get_dummies(s)
한 줄당 하나씩
df.dot(df.columns) 0 a 1 a 2 a 3 b 4 b 5 b 6 c 7 c 8 d 9 d 10 e 11 f 12 g 13 h dtype: object
다시! 행당 하나만 가정
i, j = np.where(df) pd.Series(df.columns[j], i) 0 a 1 a 2 a 3 b 4 b 5 b 6 c 7 c 8 d 9 d 10 e 11 f 12 g 13 h dtype: category Categories (8, object): [a, b, c, d, e, f, g, h]
행당 하나씩 가정하지 않음
i, j = np.where(df) pd.Series(dict(zip(zip(i, j), df.columns[j]))) 0 0 a 1 0 a 2 0 a 3 1 b 4 1 b 5 1 b 6 2 c 7 2 c 8 3 d 9 3 d 10 4 e 11 5 f 12 6 g 13 7 h dtype: object
우리가 행당 1 개를 가정하지 않고 색인을 삭제하면
i, j = np.where(df) pd.Series(dict(zip(zip(i, j), df.columns[j]))).reset_index(-1, drop=True) 0 a 1 a 2 a 3 b 4 b 5 b 6 c 7 c 8 d 9 d 10 e 11 f 12 g 13 h dtype: object
from https://stackoverflow.com/questions/26762100/reconstruct-a-categorical-variable-from-dummies-in-pandas by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Selenium Compound 클래스 이름은 허용되지 않습니다. (0) | 2018.10.14 |
---|---|
[PYTHON] 문자열 목록의 모든 요소 제거 (0) | 2018.10.14 |
[PYTHON] 문자열을 연산자로 변환합니다. (0) | 2018.10.14 |
[PYTHON] numpy 배열을 위해 해시 할 수있는 가장 효율적인 속성 (0) | 2018.10.14 |
[PYTHON] 파이썬으로 셀렌 웹 드라이버로 텍스트를 얻는 법 (0) | 2018.10.14 |