2017-12-13 118 views
9

Tôi có một danh sách các giao dịch/bản ghi trong Python với số khác nhau hoặc các yếu tố, như thế này:Liệt kê các bộ dữ liệu vào bảng nhị phân?

lst = [('apple','banana','carrots'),('apple',),('banana','carrots',)] 

Tôi muốn để lưu trữ danh sách này trong một dạng bảng (tốt nhất trong một pd.DataFrame) như thế này:

apple banana carrots 
0  1  1  1 
1  1  0  0 
2  0  1  1 

Nhưng nếu cố gắng để chuyển đổi trực tiếp sử dụng pd.DataFrame, tôi nhận được thay vì của mình:

pd.DataFrame(lst) 
 0  1  2 
0 apple banana carrots 
1 apple  None  None 
2 banana carrots  None 

Làm cách nào để chuyển đổi loại danh sách này thành bảng nhị phân?

Trả lời

6

Hãy thử get_dummies + groupby + sum -

pd.get_dummies(pd.DataFrame(lst)).groupby(by=lambda x: x.split('_')[1], axis=1).sum() 

    apple banana carrots 
0  1  1  1 
1  1  0  0 
2  0  1  1 

này nên được khá nhanh.

+1

Không chỉ khá nhanh, nhưng siêu dooper nhanh – Dark

+0

Thực sự nhanh chóng thực sự! Tôi mất 50 giây để xử lý danh sách 4,5 triệu yếu tố! Cảm ơn bạn COLDSPEED !! –

+0

@AdrianoArantes bạn được chào đón! Câu trả lời được chấp nhận trước đó bao lâu? –

8

Các phương pháp sau đây:

  1. Xác định lst

  2. Tìm tất cả các chuỗi duy nhất trong lst

  3. lần xuất hiện Đếm trong từng tuple trong danh sách

  4. Tạo datafram e

được thực hiện ở đây:

import pandas as pd 
import numpy as np 

lst = [('apple','banana','carrots'),('apple',),('banana','carrots',)] 
cols = np.unique(sum(tuple(lst),())) 
data = [[i.count(j) for j in cols] for i in lst] 
df = pd.DataFrame(columns=cols, data=data) 

Output:

apple banana carrots 
0  1  1  1 
1  1  0  0 
2  0  1  1 
+0

điều này sẽ không là nhị phân nếu một phần tử xuất hiện nhiều lần trong một hàng – Nate

+0

@Nếu đúng, mặc dù nó sẽ là nhị phân nếu đầu vào có cùng định dạng như trong câu hỏi. – Robbie

+0

Cảm ơn @Robbie, giải pháp của bạn hoạt động tốt trong trường hợp của tôi và vâng, đối với các vấn đề của tôi, mỗi phần tử chỉ xuất hiện một lần mỗi hàng. –

0

Bạn có thể thử này:

import itertools 
class Table: 
    def __init__(self, data): 
     self.lst = data 
     self.headers = headers = list(set(itertools.chain(*self.lst))) 
     self.new_count = {i:[b.count(i) for b in self.lst] for i in self.headers} 
    def __getitem__(self, row): 
     if isinstance(row, int): 
      return [d[row] for c, d in sorted(self.new_count.items(), key=lambda x:x[0])] 
     return self.new_count[row] 
    def __repr__(self): 
     return ' '.join(sorted(self.new_count.keys()))+'\n'+'\n'.join('{}. {}'.format(i, ' '.join(map(str, d))) for i, d in enumerate(zip(*[e[-1] for e in sorted(self.new_count.items(), key=lambda x:x[0])]))) 

lst = [('apple','banana','carrots'),('apple',),('banana','carrots',)] 
t = Table(lst) 
print(t) 

Output:

apple banana carrots 
0. 1 1 1 
1. 1 0 0 
2. 0 1 1 
0

Tạo danh sách tạm thời với các mục được chuyển đổi thành nhị phân, sau đó sử dụng Dataframe Viết vòng lặp chuyển đổi từng mục thành nhị phân.

def pad_collection(collection, pad_value): 
    sorted_collection = sorted(collection, key=lambda tup: len(tup)) 
    max_length = len(sorted_collection[-1]) 
    for item in collection: 
     for i in range (max_length - len(item)): 
      item.append(pad_value) 
    return collection 

def convert_to_binary(collection): 
    result = [] 
    padded_collection = pad_collection(collection) 
    for i in padded_collection: 
     temp = [] 
     for element in i: 
      new_element = int(bool(element)) 
      temp.append(new_element) 
     result.append(tuple(temp)) 
    return padded_collection 
10

này là rất đơn giản nếu bạn sử dụng value_counts trên cột tức là

pd.DataFrame(lst).apply(pd.value_counts,1).fillna(0) 

    apple banana carrots 
0 1.0  1.0  1.0 
1 1.0  0.0  0.0 
2 0.0  1.0  1.0 
+0

'value_counts' có vẻ như 'thuộc về' với bạn :-) – Wen

+0

Haha có thể, cảm thấy thích sử dụng nó – Dark

+0

Xin chào @Dark. Cảm ơn vì giải pháp của bạn. Nó có vẻ đơn giản, nhưng phải mất quá nhiều thời gian để chạy. Danh sách của tôi thực sự có hơn 4 triệu yếu tố. Và vì lý do nào đó, giải pháp của Robbie chạy nhanh hơn nhiều. Bạn có thể giúp tôi hiểu tại sao không? Cảm ơn –

3

Chỉ stackget_dummies

pd.DataFrame(lst).stack().str.get_dummies().sum(level=0) 
Out[114]: 
    apple banana carrots 
0  1  1  1 
1  1  0  0 
2  0  1  1 
+0

Kiểm tra câu trả lời của tôi khi bạn có thể! –

+1

@ cᴏʟᴅsᴘᴇᴇᴅ sử dụng tốt của groupby !! – Wen

0

Bạn có thể thử trong logic thuần túy mà không cần nhập bất kỳ thành phần bên ngoài,

lst = [('apple','banana','carrots'),('apple',),('banana','carrots',)] 

track_uniqu=[] 
for i in lst: 
    for k in i: 

     if k not in track_uniqu: 
      track_uniqu.append(k) 

final={} 
for i,j in enumerate(lst): 

    dummy=[0]*len(track_uniqu) 

    for k in j: 
     if k in track_uniqu: 

      dummy[track_uniqu.index(k)]=1 
      final[i]=dummy 
     else: 
      pass 
print(final) 

đầu ra:

{0: [1, 1, 1], 1: [1, 0, 0], 2: [0, 1, 1]} 

Kết quả là ở định dạng dict nhưng bạn có thể tạo dữ liệu bảng từ dict này như bạn muốn.

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