2017-01-01 49 views
6

Tôi có dữ liệu của các hình thức sau đây:Đếm giá trị duy nhất sử dụng gấu trúc groupby

giá trị
df = pd.DataFrame({ 
    'group': [1, 1, 2, 3, 3, 3, 4], 
    'param': ['a', 'a', 'b', np.nan, 'a', 'a', np.nan] 
}) 
print(df) 

# group param 
# 0  1  a 
# 1  1  a 
# 2  2  b 
# 3  3 NaN 
# 4  3  a 
# 5  3  a 
# 6  4 NaN 

Non-null trong nhóm này luôn luôn giống nhau. Tôi muốn tính giá trị không null cho mỗi nhóm (nơi nó tồn tại) một lần, và sau đó tìm tổng số đếm cho mỗi giá trị.

tôi đang làm điều này theo cách (clunky và không hiệu quả) như sau:

param = [] 
for _, group in df[df.param.notnull()].groupby('group'): 
    param.append(group.param.unique()[0]) 
print(pd.DataFrame({'param': param}).param.value_counts()) 

# a 2 
# b 1 

tôi chắc chắn rằng có một cách để làm điều này sạch hơn và không cần dùng một vòng lặp, nhưng tôi chỉ có thể' t dường như làm việc nó ra. Bất kì sự trợ giúp nào đều được đánh giá cao.

Trả lời

11

Tôi nghĩ rằng bạn có thể sử dụng SeriesGroupBy.nunique:

print (df.groupby('param')['group'].nunique()) 
param 
a 2 
b 1 
Name: group, dtype: int64 

Một giải pháp với unique, sau đó tạo mới df bởi DataFrame.from_records, định hình lại để Series bởi stack và cuối cùng value_counts:

a = df[df.param.notnull()].groupby('group')['param'].unique() 
print (pd.DataFrame.from_records(a.values.tolist()).stack().value_counts()) 
a 2 
b 1 
dtype: int64 
+0

tôi thử nghiệm nó với 'df = pd.DataFrame ({ 'nhóm': [1, 1, 2, 3, 3, 3, 4], ' param ': [' a ',' c ',' b ', np.nan,' c ',' a ', np.nan] }) ', nhưng mã của bạn trả về kết quả đầu ra khác nhau vì chỉ sử dụng phần tử duy nhất đầu tiên của liệt kê trong mỗi 'nhóm'. Mã của tôi trả về tất cả các giá trị duy nhất. Vui lòng kiểm tra nếu tôi hiểu bạn cần gì. Cảm ơn bạn. – jezrael

+0

Mã của bạn làm những gì tôi cần - cảm ơn sự giúp đỡ của bạn! Tôi đã chọn phần tử đầu tiên chỉ để '.unique()' không trả về một mảng. – user1684046

4

Đây chỉ là một là add-on cho giải pháp trong trường hợp bạn muốn tính toán không chỉ các giá trị duy nhất mà còn các hàm tổng hợp khác:

df.groupby(['group']).agg(['min','max','count','nunique']) 

Hy vọng bạn tìm thấy nó hữu ích

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