2016-06-09 13 views
1

Ich versuche, einzigartige Kombinationen von Telefonnummern und Werte zu erhalten, wo Telefonnummern und Werte sind jeweils in zwei möglichen Spalten.Python Pandas - einzigartige Kombinationen von Variablen in mehreren spezifischen Spalten

Zum Beispiel:

df = pd.DataFrame({'phone1':[4567890876, 4567890876, 9178889999, 3237800876], 
        'phone2':[4567890876, 4567890876, 9178889999, 2139990000], 
        'num1':[1,2,3,3], 
        'num2':[5,2,3,1]}) 

Die einzigartigen Werte würde wie folgt aussehen:

phone   num 
4567890876 1 
4567890876 2 
4567890876 5 
9178889999 3 
2139990000 1 
2139990000 3 
3237800876 1 
3237800876 3 

ich zwei Wege gefunden, dies zu tun, aber sie beide fühlen sich sehr ungeschickt/falsch:

1) Kopieren des df viermal (phone1/num1, phone1/num2, phone2/num1, phone2/num2), Verketten und Löschen von Duplikaten

Indexing

2) durch die Telefonfelder, Stapel, dann die Indizierung durch die Zahlenfelder und Stapel wieder und Abwurf dupliziert

Wenn jemand besser/Reiniger/schnelle Ideen, wäre es sehr zu schätzen!

+0

Warum erscheinen '2139990000' und' 3237800876' zweimal im resultierenden DF? – MaxU

Antwort

2

pd.melt können mehrere Spalten in einer Wertspalte (und einer Variablenspalte) zusammengeführt werden. Man könnte es einmal verwenden, um die num1 und num2 Spalten zu verschmelzen, und ein zweites Mal die phone1 und phone2 Spalten zu vereinigen:

import pandas as pd 
df = pd.DataFrame({'phone1':[4567890876, 4567890876, 9178889999, 3237800876], 
        'phone2':[4567890876, 4567890876, 9178889999, 2139990000], 
        'num1':[1,2,3,3], 
        'num2':[5,2,3,1]}) 

melted = pd.melt(df, id_vars=['phone1', 'phone2'], var_name='numvar', value_name='num') 
melted = pd.melt(melted, id_vars=['numvar', 'num'], value_name='phone') 
melted = melted[['num', 'phone']] 
melted = melted.drop_duplicates() 
print(melted) 

ergibt

num  phone 
0  1 4567890876 
1  2 4567890876 
2  3 9178889999 
3  3 3237800876 
4  5 4567890876 
7  1 3237800876 
11 3 2139990000 
15 1 2139990000 

Erklärung: Verwenden Sie id_vars zu verhindern, dass die phone1 und phone2 Säulen geschmolzen werden. Im Folgenden zeigt das Ergebnis der num1 und num2 Spalten des Schmelzens:

In [166]: melted = pd.melt(df, id_vars=['phone1', 'phone2'], var_name='numvar', value_name='num'); melted 
Out[166]: 
     phone1  phone2 numvar num 
0 4567890876 4567890876 num1 1 
1 4567890876 4567890876 num1 2 
2 9178889999 9178889999 num1 3 
3 3237800876 2139990000 num1 3 
4 4567890876 4567890876 num2 5 
5 4567890876 4567890876 num2 2 
6 9178889999 9178889999 num2 3 
7 3237800876 2139990000 num2 1 

Dann pd.melt wieder anwenden, um die phone1 und phone2 Spalten zu einem kombinieren:

In [168]: pd.melt(melted, id_vars=['numvar', 'num'], value_name='phone') 
Out[168]: 
    numvar num variable  phone 
0 num1 1 phone1 4567890876 
1 num1 2 phone1 4567890876 
2 num1 3 phone1 9178889999 
3 num1 3 phone1 3237800876 
4 num2 5 phone1 4567890876 
5 num2 2 phone1 4567890876 
6 num2 3 phone1 9178889999 
7 num2 1 phone1 3237800876 
8 num1 1 phone2 4567890876 
9 num1 2 phone2 4567890876 
10 num1 3 phone2 9178889999 
11 num1 3 phone2 2139990000 
12 num2 5 phone2 4567890876 
13 num2 2 phone2 4567890876 
14 num2 3 phone2 9178889999 
15 num2 1 phone2 2139990000 

Tropfen Duplikate und Drop die numvar und variable Spalten und Sie erhalten das gewünschte Ergebnis (wenn auch in einer anderen Reihenfolge).

+0

Was ist los mit Ihrer ersten Lösung - 'lreshape()'? Es hat mir mehr gefallen :) – MaxU

+1

@MaxU: 'pd.lreshape (df, {'phone': ['phone1', 'phone2'], 'num': ['num1', 'num2']}). Drop_duplicates () 'hat die richtige Form, gibt aber das falsche Ergebnis. Es funktioniert so, als ob es die Spalten "phone1" und "phone2" verkettet, und ähnlich für die Spalten "num1" und "num2", aber nicht "num1" mit * sowohl * 'phone1' und' phone2' assoziieren 'num2' mit beiden' phone' Spalten. Es verbindet nur 'num1' mit' phone1' und 'num2' mit' phone2'. – unutbu

+0

danke für die Erklärung! – MaxU