2017-01-21 61 views
5

Có thể tôi thiếu điều hiển nhiên.Pandas: Sử dụng groupby trên mỗi phần tử trong danh sách

Tôi có một dataframe gấu trúc trông như thế này:

id  product    categories 
    0  Silmarillion   ['Book', 'Fantasy'] 
    1  Headphones   ['Electronic', 'Material'] 
    2  Dune     ['Book', 'Sci-Fi'] 

Tôi muốn sử dụng chức năng groupby để đếm số lần xuất hiện của mỗi phần tử trong cột loại, vì vậy đây sẽ là kết quả

Book  2 
Fantasy 1 
Electronic 1 
Material 1 
Sci-Fi  1 

Tuy nhiên khi tôi thử sử dụng chức năng nhóm, gấu trúc đếm số lần xuất hiện của toàn bộ danh sách thay vì tách các phần tử. Tôi đã thử nhiều cách khác nhau để xử lý việc này, sử dụng các bộ dữ liệu hoặc chia tách, nhưng điều này đến nay tôi đã không thành công.

+3

Ngoài: gấu trúc không hỗ trợ đầy đủ các mục không vô hướng vào thời điểm này, và đôi khi bạn có thể nhận được những thất bại bí ẩn khi sử dụng chúng. Nó thường an toàn hơn để làm lại khung của bạn sao cho mỗi hàng chỉ chứa các mục vô hướng. – DSM

Trả lời

5

Bạn có thể bình thường hóa các hồ sơ bằng cách chồng sau đó họ gọi value_counts():

pd.DataFrame(df['categories'].tolist()).stack().value_counts() 
Out: 
Book   2 
Fantasy  1 
Material  1 
Sci-Fi  1 
Electronic 1 
dtype: int64 
4

thử điều này:

In [58]: df['categories'].apply(pd.Series).stack().value_counts() 
Out[58]: 
Book   2 
Fantasy  1 
Electronic 1 
Sci-Fi  1 
Material  1 
dtype: int64 
+0

@ayhan, tại sao bạn xóa giải pháp của mình? Tôi đoán nó tốt hơn tôi – MaxU

+0

Làm việc như một sự quyến rũ, cảm ơn! – Skum

+0

@MaxU '.apply (pd.Series)' có vẻ rõ ràng hơn 'pd.DataFrame (ser.tolist())'. Mỏ của tôi trông giống như một tác dụng phụ có thể không hoạt động trong tương lai. – ayhan

5

Bạn cũng có thể gọi pd.value_counts trực tiếp trên một danh sách.
Bạn có thể tạo danh sách thích hợp qua numpy.concatenate, itertools.chain, hoặc cytoolz.concat

from cytoolz import concat 
from itertools import chain 

cytoolz.concat

pd.value_counts(list(concat(df.categories.values.tolist()))) 

itertools.chain

pd.value_counts(list(chain(*df.categories.values.tolist()))) 

numpy.unique + numpy.concatenate

u, c = np.unique(np.concatenate(df.categories.values), return_counts=True) 
pd.Series(c, u) 

Tất cả mang lại

Book   2 
Electronic 1 
Fantasy  1 
Material  1 
Sci-Fi  1 
dtype: int64 

thời gian thử nghiệm

enter image description here

+1

wow! đây là nhanh! – MaxU

+1

Cảm ơn bạn @NickilMaveli ... Tôi đã bỏ lỡ điều đó ;-) – piRSquared

+0

Tôi nhận được sự nhầm lẫn đó ;-) –

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