2011-02-08 41 views
6

Chỉnh sửa tiêu đề: viết hoa cố định và 'cho python' được thêm vào.Nhóm một chuỗi bằng Python

Có cách nào tốt hơn hoặc chuẩn hơn để làm những gì tôi mô tả không? Tôi muốn đầu vào như thế này:

[1, 1, 1, 0, 2, 2, 0, 2, 2, 0, 0, 3, 3, 0, 1, 1, 1, 1, 1, 2, 2, 2]

để được chuyển đổi như sau:

[0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0]

hoặc, thậm chí tốt hơn, một cái gì đó như thế này (mô tả đầu ra tương tự cách khác nhau, nhưng bây giờ không giới hạn số nguyên):

nhãn: [1, 2, 3, 1, 2]

vị trí (trong đó 1 xác định vị trí chiếm đóng đầu tiên, theo lô đất matplotlib của tôi): [2, 7, 12.5, 17, 21]

Dữ liệu đầu vào là phân loại dữ liệu phân loại một tính năng phân loại mà tôi muốn chỉ gắn nhãn một lần cho nhóm. Tôi sẽ sử dụng 2 trục cho hai biến khác nhau, nhưng tôi nghĩ rằng đó là ngoài điểm cho bây giờ.

Lưu ý: Hình ảnh này không phản ánh một trong hai tập hợp dữ liệu mẫu - chỉ để xem xét ý tưởng nhóm các danh mục cùng nhau. Nhóm nên được gắn nhãn tại x = 5, vì có khoảng trống giữa hai nhóm dữ liệu đầu tiên và thứ hai cho các nhóm dữ liệu dọc và 0 là dòng ở bên phải.

Image demonstrating placement of tick marks in the center of a category of data

Đây là những gì tôi đã có:

data = [1, 1, 1, 2, 2, 2, 2, 2, 3, 4, 3, 2, 2, 1, 1, 1, 1] 
last = None 
runs = [] 
labels = [] 
run = 1 
for x in data: 
    if x in (last, 0): 
     run += 1 
    else: 
     runs.append(run) 
     run = 1 
     labels.append(x) 
    last = x 
runs.append(run) 
runs.pop(0) 
labels.append(x) 
tick_positions = [0] 
last_run = 1 
for run in runs: 
    tick_positions.append(run/2.0+last_run/2.0+tick_positions[-1]) 
    last_run = run 
tick_positions.pop(0) 
print tick_positions 

Trả lời

8

Để có được các nhãn bạn có thể sử dụng itertools groupby:

>>> import itertools 
>>> numbers = [1, 1, 1, 0, 2, 2, 0, 2, 2, 0, 0, 3, 3, 0, 1, 1, 1, 1, 1, 2, 2, 2] 
>>> list(k for k, g in itertools.groupby(numbers)) 
[1, 0, 2, 0, 2, 0, 3, 0, 1, 2] 

Và để loại bỏ các số không bạn có thể sử dụng một sự hiểu biết :

>>> list(k for k, g in itertools.groupby(x for x in numbers if x != 0)) 
[1, 2, 3, 1, 2] 

Nếu bạn muốn nhận các vị trí quá, bạn sẽ phải lặp qua danh sách chính mình như bạn đã làm. groupby không theo dõi điều đó cho bạn.

+1

Đó chính xác là những gì tôi tưởng tượng đã tồn tại ở đâu đó - tôi được nhắc rằng 'ở đâu đó' hầu như luôn là công cụ lặp. Cảm ơn. – Thomas

+2

1) Các vị trí quan trọng quá 2) Điều đó '0' giữa hai chuỗi của' 2' cũng nên được bỏ qua. Tôi đoán không có tùy chọn nhưng bằng cách nào đó tạo ra rằng mảng trung gian, chỉ cần nhóm tất cả các giá trị lặp lại là không đủ. – rsenna

+0

rsenna là đúng, điều này không làm việc cho tất cả mọi thứ tôi cần, nhưng tôi mong đợi là đóng hộp một giải pháp như tôi sẽ tìm thấy - trông giống như câu trả lời chính xác cho câu hỏi của tôi sẽ là "không", nhưng đó là nhàm chán. – Thomas

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