2017-02-21 17 views
3

У меня есть Dataframe, который выглядит следующим образом:Pythonic способ создания пары значений в колонке в dataframe

OwnerID Value 
1   A 
1   B 
1   C 
1   D 

Это сокращенный вариант, у меня есть тысячи значений OwnerID. Я хотел бы создать пары для столбца Value, где каждый Value сопряжен с любыми другими Value и имеет результат как список пар.

Например, для OwnerID 1, ResultSet должны быть следующие списки:

[A,B] 

[A,C] 

[A,D] 

[B,C] 

[B,D] 

[C,D] 

Я мог бы написать 2 for петли для достижения этой цели, но это не будет очень эффективным и вещий. Кто-нибудь знает лучший способ достичь этого?

Любая помощь будет высоко оценена.

+0

@ B.Eckles да, только заметил, что. Виноват. – spicypumpkin

+0

@Posh_Pumpkin lol Я только заметил, что вы это заметили. ; D –

ответ

4
import itertools as iter 
df2 = df.groupby('OwnerID').Value.apply(lambda x: list(iter.combinations(x, 2))) 

возвращает желаемый результат для каждого уникального идентификатора владельца

OwnerID 
1 [(A, B), (A, C), (A, D), (B, C), (B, D), (C, D)] 
+1

@Patthebug, я только что отредактировал ответ, чтобы заботиться о каждом уникальном владельце id – Vaishali

+0

Очень приятное решение! – MaxU

+0

@VaishaliGargThanks для вашего ответа. – Patthebug

1

itertools - это все, что вам нужно.

В зависимости от того, как вы хотите их комбинировать, попробуйте либо permutations, либо combinations, например.

0

Try itertools

import itertools 

list(itertools.combinations(['a','b','c','d'], 2)) 

#result: [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')] 
0
val = df['Value'].values 
length = len(val) 
pairs = [[val[i],val[j]] for i in xrange(length) for j in xrange(length) if i!=j] 
5

панды решение (с использованием .merge() и .query() методов):

данных:

In [10]: df 
Out[10]: 
    OwnerID Value 
0  1  A 
1  1  B 
2  1  C 
3  1  D 
4  2  X 
5  2  Y 
6  2  Z 

Решение:

In [9]: pd.merge(df, df, on='OwnerID', suffixes=['','2']).query("Value != Value2") 
Out[9]: 
    OwnerID Value Value2 
1   1  A  B 
2   1  A  C 
3   1  A  D 
4   1  B  A 
6   1  B  C 
7   1  B  D 
8   1  C  A 
9   1  C  B 
11  1  C  D 
12  1  D  A 
13  1  D  B 
14  1  D  C 
17  2  X  Y 
18  2  X  Z 
19  2  Y  X 
21  2  Y  Z 
22  2  Z  X 
23  2  Z  Y 

Если вам нужны только списки:

In [17]: pd.merge(df, df, on='OwnerID', suffixes=['','2']) \ 
      .query("Value != Value2") \ 
      .filter(like='Value').values 
Out[17]: 
array([['A', 'B'], 
     ['A', 'C'], 
     ['A', 'D'], 
     ['B', 'A'], 
     ['B', 'C'], 
     ['B', 'D'], 
     ['C', 'A'], 
     ['C', 'B'], 
     ['C', 'D'], 
     ['D', 'A'], 
     ['D', 'B'], 
     ['D', 'C'], 
     ['X', 'Y'], 
     ['X', 'Z'], 
     ['Y', 'X'], 
     ['Y', 'Z'], 
     ['Z', 'X'], 
     ['Z', 'Y']], dtype=object) 
+0

.query предоставляется pandas? Не могу поверить, что я пропустил такой замечательный метод! – AsheKetchum

+1

@AsheKetchum, да, я добавил ссылку на документы – MaxU