Pandas veri çerçevesindeki seçili sütunlarda benzersiz değer kombinasyonları ve sayısı


111

Verilerim pandalar veri çerçevesinde aşağıdaki gibi var:

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

Yani, verilerim şöyle görünüyor

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

Onu başka bir veri çerçevesine dönüştürmek istiyorum. Beklenen çıktı aşağıdaki python betiğinde gösterilebilir:

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

Yani beklediğim çıktı şuna benziyor

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

Aslında, aşağıdaki komutu kullanarak tüm kombinasyonları bulup saymayı başarabilirim: mytable = df1.groupby(['A','B']).size()

Ancak bu tür kombinasyonların tek bir sütunda olduğu ortaya çıkıyor. Bir kombinasyondaki her bir değeri farklı bir sütuna ayırmak ve ayrıca sayım sonucu için bir sütun daha eklemek istiyorum. Bunu yapmak mümkün mü? Önerilerinizi alabilir miyim? Şimdiden teşekkür ederim.

Yanıtlar:


178

Şunları yapabilirsiniz groupbyCOLS 'A' ve 'B' ve çağrı üzerine sizeve sonra reset_indexve renameoluşturulan sütuna:

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

Güncelleme

Küçük bir açıklama, 2 sütun üzerinde gruplandırarak, bu gruplar A ve B değerlerinin aynı olduğu satırları size, benzersiz grupların sayısını döndüren diyoruz :

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

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

Şimdi gruplanmış sütunları geri yüklemek için şunu diyoruz 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

Bu, endeksleri geri yükler, ancak boyut toplamı oluşturulan bir sütuna dönüştürülür 0, bu nedenle bunu yeniden adlandırmalıyız:

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

groupbygruplanmış sütunları dizin yapmaması için as_indexayarlayabileceğimiz argümanı kabul ediyor False, ancak bu bir a oluşturur seriesve yine de dizinleri geri yüklemeniz gerekir.

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

Biraz ilgili, benzersiz kombinasyonları arıyordum ve şu yöntemi buldum:

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

Ve sadece tüm kombinasyonların benzersiz olduğunu iddia etmek istiyorsanız:

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

Bilmiyordum set_index(). Sıraları groupby()belirli bir ortak sütun çiftiyle birlikte gruplamak için kullanmaya devam etti. Harika, teşekkürler!
user3290553

0

@ EdChum'un çok güzel cevabını bir işleve yerleştirmek count_unique_index. Benzersiz yöntem, veri çerçevelerinde değil, yalnızca panda serilerinde işe yarar. Aşağıdaki işlev, R'deki benzersiz işlevin davranışını yeniden oluşturur :

Unique, x gibi ancak yinelenen öğeler / satırlar kaldırılmış bir vektör, veri çerçevesi veya dizi döndürür.

Ve OP tarafından istenen olayların sayısını ekler.

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

Bununla zaman testi yapmadım ama denemek eğlenceliydi. Temel olarak iki sütunu bir sütun sütununa dönüştürün. Şimdi dönüştürmek olduğunu yapın dataframe özgü unsurları bulur 'value_counts ()' ve sayıları onları. Tekrar zip ile oynayın ve sütunları istediğiniz sıraya koyun. Muhtemelen adımları daha zarif hale getirebilirsiniz ancak bu sorun için tuple ile çalışmak bana daha doğal geliyor

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']]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.