ชุดค่าผสมที่ไม่ซ้ำกันในคอลัมน์ที่เลือกในกรอบข้อมูลแพนด้าและจำนวน


114

ฉันมีข้อมูลของฉันอยู่ในกรอบข้อมูลแพนด้าดังนี้:

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']})

ดังนั้นข้อมูลของฉันมีลักษณะเช่นนี้

----------------------------
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
-----------------------------

ฉันต้องการแปลงเป็นกรอบข้อมูลอื่น ผลลัพธ์ที่คาดหวังสามารถแสดงในสคริปต์ python ต่อไปนี้:

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

ผลลัพธ์ที่คาดหวังของฉันจะเป็นแบบนี้

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

จริงๆแล้วฉันสามารถค้นหาชุดค่าผสมทั้งหมดและนับได้โดยใช้คำสั่งต่อไปนี้: mytable = df1.groupby(['A','B']).size()

อย่างไรก็ตามปรากฎว่าชุดค่าผสมดังกล่าวอยู่ในคอลัมน์เดียว ฉันต้องการแยกแต่ละค่าในการรวมกันเป็นคอลัมน์อื่นและเพิ่มอีกหนึ่งคอลัมน์สำหรับผลลัพธ์ของการนับ เป็นไปได้หรือไม่? ฉันขอคำแนะนำได้ไหม ขอบคุณล่วงหน้า.

คำตอบ:


188

คุณสามารถgroupbyในคอลัมน์ 'A' และ 'B' และโทรsizeแล้วreset_indexและrenameคอลัมน์ที่สร้าง:

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

อัพเดต

คำอธิบายเล็กน้อยโดยการจัดกลุ่มใน 2 คอลัมน์นี้จะจัดกลุ่มแถวที่ค่า A และ B เหมือนกันเราเรียกว่าsizeซึ่งส่งคืนจำนวนกลุ่มที่ไม่ซ้ำ

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

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

ดังนั้นในการกู้คืนคอลัมน์ที่จัดกลุ่มเราเรียกว่า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

สิ่งนี้จะคืนค่าดัชนี แต่การรวมขนาดจะกลายเป็นคอลัมน์ที่สร้างขึ้น0ดังนั้นเราต้องเปลี่ยนชื่อสิ่งนี้:

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

groupbyไม่ยอมรับอาร์กิวเมนต์as_indexที่เราสามารถตั้งค่าFalseเพื่อไม่ให้คอลัมน์ที่จัดกลุ่มเป็นดัชนี แต่สิ่งนี้จะสร้าง a seriesและคุณยังคงต้องกู้คืนดัชนีและอื่น ๆ ... :

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

2

เกี่ยวข้องกันเล็กน้อยฉันกำลังมองหาชุดค่าผสมที่เป็นเอกลักษณ์และฉันคิดวิธีนี้:

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

และหากคุณต้องการยืนยันว่าชุดค่าผสมทั้งหมดไม่ซ้ำกัน:

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

ไม่ทราบเกี่ยวกับset_index(). พยายามใช้groupby()เพื่อจัดกลุ่มแถวเข้าด้วยกันโดยมีคู่คอลัมน์ทั่วไป เยี่ยมมากขอบคุณ!
user3290553

0

วาง @ คำตอบที่ดีมาก EdChum count_unique_indexเข้าสู่ฟังก์ชั่น วิธีการที่ไม่ซ้ำกันใช้ได้เฉพาะกับชุดหมีแพนด้าเท่านั้นไม่ใช่ในเฟรมข้อมูล ฟังก์ชันด้านล่างจะจำลองลักษณะการทำงานของฟังก์ชันเฉพาะใน R:

unique ส่งคืนเวกเตอร์เฟรมข้อมูลหรืออาร์เรย์เช่น x แต่ลบองค์ประกอบ / แถวที่ซ้ำกันออกไป

และเพิ่มจำนวนเหตุการณ์ที่เกิดขึ้นตามที่ 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

ฉันยังไม่ได้ทดสอบเรื่องนี้ แต่มันสนุกมากที่ได้ลอง โดยทั่วไปจะแปลงสองคอลัมน์ให้เป็นหนึ่งคอลัมน์ของสิ่งทู ตอนนี้แปลงที่จะ dataframe ให้ทำ 'value_counts () ซึ่งพบว่าองค์ประกอบที่ไม่ซ้ำกันและนับพวกเขา ใส่ซิปอีกครั้งแล้ววางคอลัมน์ตามลำดับที่คุณต้องการ คุณอาจทำให้ขั้นตอนต่างๆดูหรูหราขึ้นได้ แต่การทำงานกับสิ่งทอดูเป็นธรรมชาติสำหรับฉันสำหรับปัญหานี้

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']]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.