2013-08-02 31 views
7

Tôi đang cố gắng thực hiện một số phân tích hồi quy tuyến tính, tôi có một số tính năng phân loại mà tôi chuyển đổi thành các biến giả sử dụng get_dummies siêu tuyệt vời.Nhận tập hợp con của các biến giả thường xuyên nhất trong gấu trúc

Vấn đề tôi gặp phải là, khung dữ liệu quá lớn khi tôi thêm tất cả các yếu tố của các danh mục.

Có cách nào (sử dụng get_dummies hoặc phương thức phức tạp hơn) để chỉ tạo các biến giả của các cụm từ thường xuyên nhất thay vì tất cả chúng?

Trả lời

0

Trước tiên, bạn có thể sử dụng value_counts để xem đó là những thường xuyên nhất:

In [11]: s = pd.Series(list('aabccc')) 

In [12]: s 
Out[12]: 
0 a 
1 a 
2 b 
3 c 
4 c 
5 c 
dtype: object 

In [13]: s.value_counts() 
Out[13]: 
c 3 
a 2 
b 1 
dtype: int64 

Các giá trị đó là thường xuyên nhất (ví dụ như tất cả ngoại trừ hai người đầu tiên):

In [14]: s.value_counts().index[2:] 
Out[14]: Index([u'b'], dtype=object) 

Bạn có thể đơn giản replace tất cả các sự cố này với NaN:

In [15]: s1 = s.replace(s.value_counts().index[2:], np.nan) 

In [16]: s1 
Out[16]: 
0  a 
1  a 
2 NaN 
3  c 
4  c 
5  c 
dtype: object 

và thực hiện get_dummies (mà tôi nghĩ nên bỏ qua NaN, nhưng có một lỗi, vì thế mà notnull hack):

In [16]: pd.get_dummies(s1[s1.notnull()]) 
Out[16]: 
    a c 
0 1 0 
1 1 0 
3 0 1 
4 0 1 
5 0 1 

Nếu bạn muốn bao gồm những kết quả mà bạn có thể sử dụng một trình giữ chỗ khác nhau (ví dụ '_').

+0

Oh cripes có vẻ như có một lỗi trong 'get_dummies', nó không bỏ qua NaN mà là làm điều gì đó kỳ lạ ... –

5

sử dụng value_counts() để làm đếm tần số, và sau đó tạo ra một mặt nạ cho các hàng mà bạn muốn giữ:

import pandas as pd 
values = pd.Series(["a","b","a","b","c","d","e","a"]) 
counts = pd.value_counts(values) 
mask = values.isin(counts[counts > 1].index) 
print pd.get_dummies(values[mask]) 

đầu ra:

a b 
0 1 0 
1 0 1 
2 1 0 
3 0 1 
7 1 0 

nếu bạn muốn tất cả các dữ liệu:

values[~mask] = "-" 
print pd.get_dummies(values) 

đầu ra:

- a b 
0 0 1 0 
1 0 0 1 
2 0 1 0 
3 0 0 1 
4 1 0 0 
5 1 0 0 
6 1 0 0 
7 0 1 0 
0

Tôi đã sử dụng câu trả lời @HYRY để viết hàm có tham số (ngưỡng) có thể được sử dụng để phân tách các giá trị phổ biến và không phổ biến (được kết hợp trong cột 'của người khác).

import pandas as pd 
import numpy as np 

# func that returns a dummified DataFrame of significant dummies in a given column 
def dum_sign(dummy_col, threshold=0.1): 

    # removes the bind 
    dummy_col = dummy_col.copy() 

    # what is the ratio of a dummy in whole column 
    count = pd.value_counts(dummy_col)/len(dummy_col) 

    # cond whether the ratios is higher than the threshold 
    mask = dummy_col.isin(count[count > threshold].index) 

    # replace the ones which ratio is lower than the threshold by a special name 
    dummy_col[~mask] = "others" 

    return pd.get_dummies(dummy_col, prefix=dummy_col.name) 
# 

Hãy tạo một số dữ liệu:

df = ['a', 'a', np.nan, np.nan, 'a', np.nan, 'a', 'b', 'b', 'b', 'b', 'b', 
      'c', 'c', 'd', 'e', 'g', 'g', 'g', 'g'] 

data = pd.Series(df, name='dums') 

Ví dụ về sử dụng:

In: dum_sign(data) 
Out: 
    dums_a dums_b dums_g dums_others 
0  1  0  0   0 
1  1  0  0   0 
2  0  0  0   1 
3  0  0  0   1 
4  1  0  0   0 
5  0  0  0   1 
6  1  0  0   0 
7  0  1  0   0 
8  0  1  0   0 
9  0  1  0   0 
10  0  1  0   0 
11  0  1  0   0 
12  0  0  0   1 
13  0  0  0   1 
14  0  0  0   1 
15  0  0  0   1 
16  0  0  1   0 
17  0  0  1   0 
18  0  0  1   0 
19  0  0  1   0 

In: dum_sign(data, threshold=0.2) 
Out: 
    dums_b dums_others 
0  0   1 
1  0   1 
2  0   1 
3  0   1 
4  0   1 
5  0   1 
6  0   1 
7  1   0 
8  1   0 
9  1   0 
10  1   0 
11  1   0 
12  0   1 
13  0   1 
14  0   1 
15  0   1 
16  0   1 
17  0   1 
18  0   1 
19  0   1 

In: dum_sign(data, threshold=0) 
Out: 
    dums_a dums_b dums_c dums_d dums_e dums_g dums_others 
0  1  0  0  0  0  0   0 
1  1  0  0  0  0  0   0 
2  0  0  0  0  0  0   1 
3  0  0  0  0  0  0   1 
4  1  0  0  0  0  0   0 
5  0  0  0  0  0  0   1 
6  1  0  0  0  0  0   0 
7  0  1  0  0  0  0   0 
8  0  1  0  0  0  0   0 
9  0  1  0  0  0  0   0 
10  0  1  0  0  0  0   0 
11  0  1  0  0  0  0   0 
12  0  0  1  0  0  0   0 
13  0  0  1  0  0  0   0 
14  0  0  0  1  0  0   0 
15  0  0  0  0  1  0   0 
16  0  0  0  0  0  1   0 
17  0  0  0  0  0  1   0 
18  0  0  0  0  0  1   0 
19  0  0  0  0  0  1   0 

Bất kỳ lời đề nghị làm thế nào để xử lý Nans? Tôi tin rằng nans không nên được coi là 'người khác'.

UPD: Tôi đã thử nghiệm nó trên một tập dữ liệu khá lớn (5 triệu obs) với 183 chuỗi khác nhau trong cột mà tôi muốn dummify. Việc triển khai mất tối đa 10 giây trên máy tính xách tay của tôi.

Các vấn đề liên quan