eindeutige Kombinationen von Werten in ausgewählten Spalten im Pandas-Datenrahmen und in der Anzahl

96

Ich habe meine Daten im Pandas-Datenrahmen wie folgt:

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

Meine Daten sehen also so aus

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

Ich möchte es in einen anderen Datenrahmen umwandeln. Die erwartete Ausgabe kann im folgenden Python-Skript angezeigt werden:

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

Meine erwartete Ausgabe sieht also so aus

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

Tatsächlich kann ich mit dem folgenden Befehl alle Kombinationen finden und zählen: mytable = df1.groupby(['A','B']).size()

Es stellt sich jedoch heraus, dass sich solche Kombinationen in einer einzigen Spalte befinden. Ich möchte jeden Wert in einer Kombination in eine andere Spalte unterteilen und eine weitere Spalte für das Ergebnis der Zählung hinzufügen. Ist das möglich? Darf ich Ihre Vorschläge haben? Vielen Dank im Voraus.

Ratchainant Thammasudjarit
quelle

Antworten:

163

Sie können groupbyin den Spalten 'A' und 'B' aufrufen sizeund dann reset_indexund renamedie generierte Spalte:

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

aktualisieren

Eine kleine Erklärung: Durch Gruppieren in den beiden Spalten werden Zeilen gruppiert, in denen A- und B-Werte gleich sind. Dies wird aufgerufen sizeund gibt die Anzahl der eindeutigen Gruppen zurück:

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

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

Um nun die gruppierten Spalten wiederherzustellen, rufen wir auf 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

Dadurch werden die Indizes wiederhergestellt, aber die Größenaggregation wird in eine generierte Spalte umgewandelt. Daher 0müssen wir diese umbenennen:

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

groupbyakzeptiert das Argument, auf as_indexdas wir hätten setzen können, Falsedamit die gruppierten Spalten nicht zum Index werden, aber dies generiert ein seriesund Sie müssten die Indizes immer noch wiederherstellen und so weiter ....:

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
EdChum
quelle
1

Etwas verwandt suchte ich nach den einzigartigen Kombinationen und fand diese Methode:

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

Und wenn Sie nur behaupten möchten, dass alle Kombinationen eindeutig sind:

df1.set_index(['A','B']).index.is_unique
Martin Alexandersson
quelle
Wusste nichts davon set_index(). Es wurde versucht, groupby()Zeilen mit einem bestimmten gemeinsamen Spaltenpaar zu gruppieren. Erstaunlich, danke!
user3290553
0

@ EdChums sehr nette Antwort in eine Funktion einfügen count_unique_index. Die einzigartige Methode funktioniert nur bei Pandas-Serien, nicht bei Datenrahmen. Die folgende Funktion gibt das Verhalten der eindeutigen Funktion in R wieder:

unique gibt einen Vektor, einen Datenrahmen oder ein Array wie x zurück, wobei jedoch doppelte Elemente / Zeilen entfernt wurden.

Und fügt eine Anzahl der vom OP angeforderten Vorkommen hinzu.

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
Paul Rougieux
quelle
0

Ich habe damit keinen Zeittest gemacht, aber es hat Spaß gemacht, es zu versuchen. Konvertieren Sie grundsätzlich zwei Spalten in eine Spalte mit Tupeln. Konvertieren nun das zu einem Datenrahmen, tun ‚value_counts ()‘ , die die einzigartigen Elemente findet und zählt sie. Spielen Sie erneut mit dem Reißverschluss und ordnen Sie die Spalten in der gewünschten Reihenfolge an. Sie können die Schritte wahrscheinlich eleganter gestalten, aber die Arbeit mit Tupeln erscheint mir für dieses Problem natürlicher

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']]
MikeB2019x
quelle