2014-11-05 11 views

답변

6
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(), 그것은 몇 년이, 그래서이 질문에 원래 요청했을 때이 잘 돌아 pandas 툴킷에 없었을 수도 있지만,이 방법은 나에게 좀 더 쉽게 보인다 here

6

참조하십시오. idxmax은 가장 큰 요소 (즉, 1이있는 요소)에 해당하는 색인을 반환합니다. 1이 발생하는 열 이름을 원하기 때문에 axis=1을 수행합니다.

EDIT : 나는 단지 문자열 대신 범주화하는 것을 신경 쓰지는 않았지만, @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