kết hợp duy nhất của các giá trị trong các cột đã chọn trong khung dữ liệu gấu trúc và đếm


96

Tôi có dữ liệu của mình trong khung dữ liệu gấu trúc như sau:

df1 = pd.DataFrame({'A':['yes','yes','yes','yes','no','no','yes','yes','yes','no'],
                   'B':['yes','no','no','no','yes','yes','no','yes','yes','no']})

Vì vậy, dữ liệu của tôi trông như thế này

----------------------------
index         A        B
0           yes      yes
1           yes       no
2           yes       no
3           yes       no
4            no      yes
5            no      yes
6           yes       no
7           yes      yes
8           yes      yes
9            no       no
-----------------------------

Tôi muốn chuyển đổi nó sang một khung dữ liệu khác. Đầu ra mong đợi có thể được hiển thị trong tập lệnh python sau:

output = pd.DataFrame({'A':['no','no','yes','yes'],'B':['no','yes','no','yes'],'count':[1,2,4,3]})

Vì vậy, kết quả mong đợi của tôi trông như thế này

--------------------------------------------
index      A       B       count
--------------------------------------------
0         no       no        1
1         no      yes        2
2        yes       no        4
3        yes      yes        3
--------------------------------------------

Trên thực tế, tôi có thể đạt được để tìm tất cả các kết hợp và đếm chúng bằng cách sử dụng lệnh sau: mytable = df1.groupby(['A','B']).size()

Tuy nhiên, nó chỉ ra rằng các kết hợp như vậy nằm trong một cột duy nhất. Tôi muốn tách từng giá trị trong một tổ hợp thành các cột khác nhau và cũng thêm một cột nữa để có kết quả đếm. Có thể làm được điều đó không? Tôi có thể có gợi ý của bạn? Cảm ơn bạn trước.

Câu trả lời:


163

Bạn có thể groupbytrên cols 'A' và 'B' và gọi sizevà sau đó reset_indexrenamecột được tạo:

In [26]:

df1.groupby(['A','B']).size().reset_index().rename(columns={0:'count'})
Out[26]:
     A    B  count
0   no   no      1
1   no  yes      2
2  yes   no      4
3  yes  yes      3

cập nhật

Giải thích một chút, bằng cách nhóm trên 2 cột, nhóm này sẽ nhóm các hàng có giá trị A và B giống nhau, chúng tôi gọi sizenó trả về số lượng nhóm duy nhất:

In[202]:
df1.groupby(['A','B']).size()

Out[202]: 
A    B  
no   no     1
     yes    2
yes  no     4
     yes    3
dtype: int64

Vì vậy, bây giờ để khôi phục các cột được nhóm, chúng tôi gọi reset_index:

In[203]:
df1.groupby(['A','B']).size().reset_index()

Out[203]: 
     A    B  0
0   no   no  1
1   no  yes  2
2  yes   no  4
3  yes  yes  3

Điều này khôi phục các chỉ số nhưng tổng hợp kích thước được chuyển thành một cột được tạo 0, vì vậy chúng tôi phải đổi tên như sau:

In[204]:
df1.groupby(['A','B']).size().reset_index().rename(columns={0:'count'})

Out[204]: 
     A    B  count
0   no   no      1
1   no  yes      2
2  yes   no      4
3  yes  yes      3

groupbychấp nhận đối số as_indexmà chúng tôi có thể đã đặt để Falsenó không làm cho các cột được nhóm thành chỉ mục, nhưng điều này tạo ra một seriesvà bạn vẫn phải khôi phục các chỉ số, v.v.:

In[205]:
df1.groupby(['A','B'], as_index=False).size()

Out[205]: 
A    B  
no   no     1
     yes    2
yes  no     4
     yes    3
dtype: int64

1

Hơi liên quan, tôi đang tìm kiếm các kết hợp độc đáo và tôi đã nghĩ ra phương pháp này:

def unique_columns(df,columns):

    result = pd.Series(index = df.index)

    groups = meta_data_csv.groupby(by = columns)
    for name,group in groups:
       is_unique = len(group) == 1
       result.loc[group.index] = is_unique

    assert not result.isnull().any()

    return result

Và nếu bạn chỉ muốn khẳng định rằng tất cả các kết hợp là duy nhất:

df1.set_index(['A','B']).index.is_unique

Không biết về set_index(). Cố gắng sử dụng groupby()để nhóm các hàng lại với nhau với một cặp cột chung cụ thể. Tuyệt vời, cảm ơn bạn!
user3290553

0

Đặt câu trả lời rất hay của @ EdChum vào một hàm count_unique_index. Phương pháp duy nhất chỉ hoạt động trên chuỗi gấu trúc, không hoạt động trên khung dữ liệu. Hàm dưới đây tái tạo hành vi của hàm duy nhất trong R:

duy nhất trả về một vectơ, khung dữ liệu hoặc mảng như x nhưng đã loại bỏ các phần tử / hàng trùng lặp.

Và thêm số lần xuất hiện theo yêu cầu của OP.

df1 = pd.DataFrame({'A':['yes','yes','yes','yes','no','no','yes','yes','yes','no'],                                                                                             
                    'B':['yes','no','no','no','yes','yes','no','yes','yes','no']})                                                                                               
def count_unique_index(df, by):                                                                                                                                                 
    return df.groupby(by).size().reset_index().rename(columns={0:'count'})                                                                                                      

count_unique_index(df1, ['A','B'])                                                                                                                                              
     A    B  count                                                                                                                                                                  
0   no   no      1                                                                                                                                                                  
1   no  yes      2                                                                                                                                                                  
2  yes   no      4                                                                                                                                                                  
3  yes  yes      3

0

Tôi chưa thực hiện kiểm tra thời gian với điều này nhưng rất vui khi thử. Về cơ bản chuyển đổi hai cột thành một cột bộ giá trị. Bây giờ chuyển đổi đó để một dataframe, làm 'value_counts ()' mà tìm thấy những yếu tố độc đáo đếm chúng. Làm lại với zip và đặt các cột theo thứ tự bạn muốn. Bạn có thể làm cho các bước thanh lịch hơn nhưng làm việc với tuples có vẻ tự nhiên hơn đối với tôi cho vấn đề này

b = pd.DataFrame({'A':['yes','yes','yes','yes','no','no','yes','yes','yes','no'],'B':['yes','no','no','no','yes','yes','no','yes','yes','no']})

b['count'] = pd.Series(zip(*[b.A,b.B]))
df = pd.DataFrame(b['count'].value_counts().reset_index())
df['A'], df['B'] = zip(*df['index'])
df = df.drop(columns='index')[['A','B','count']]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.