2016-06-09 60 views
1

我想獲得電話號碼和值的獨特組合,其中電話號碼和值分別位於兩個潛在列中。Python熊貓 - 多個特定列中的變量的獨特組合

例如:

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

的唯一值的樣子:

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

我發現兩種方法可以做到這一點,但他們都覺得很笨拙/錯誤:

1)複製df四次(phone1/num1,phone1/num2,phone2/num1,phone2/num2),連接並丟棄重複項

2)通過手機字段進行索引,堆疊,然後通過數字字段進行索引並重新堆疊,然後刪除重複副本

如果有人有更好/更清潔/更快的創意,將不勝感激!

+0

爲什麼'2139990000'和'3237800876'在結果DF中出現兩次? – MaxU

回答

2

pd.melt可以將多個列合併爲一個值列(和一個可變列)。你可以使用它曾經凝聚了num1num2列,和第二次聚結phone1phone2列:

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) 

產生

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 

說明:使用id_vars到防止phone1phone2色譜柱熔化。下面顯示熔化num1num2列結果:

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 

然後再次申請pd.meltphone1phone2列合併爲一個:

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 

刪除重複項,並刪除numvarvariable列你會得到想要的結果(儘管順序不同)。

+0

你的第一個解決方案有什麼問題 - 'lreshape()'?我更喜歡它:) – MaxU

+1

@MaxU:'pd.lreshape(df,{'phone':['phone1','phone2'],'num':['num1','num2']})。drop_duplicates( )'有正確的形式,但是給出了錯誤的結果。它的作用就像連接phone1和phone2列一樣,對於num1和num2列也是如此,但它不會將num1和* phone1和phone2關聯起來,也不會關聯'num2'包含'phone'列。它只把'num1'與'phone1'和'num2'與'phone2'聯繫起來。 – unutbu

+0

感謝您的解釋! – MaxU