2016-02-20 163 views
4

我有一个使用Postgres SQL的类似问题,但我认为这种任务在Postgres中确实很难做到,我认为python/pandas会使这更容易,尽管我仍然无法完全想出解决方案。所有可能的排列列Pandas Dataframe在同一列内

我现在有一个熊猫数据帧,看起来像这样:

df={'planid' : ['A', 'A', 'B', 'B', 'C', 'C'], 
    'x' : ['a1', 'a2', 'b1', 'b2', 'c1', 'c2']} 

df=pd.DataFrame(df) 

df 


    planid x 
0 A  a1 
1 A  a2 
2 B  b1 
3 B  b2 
4 C  c1 
5 C  c2 

我想在那里planid不等于彼此所有可能的排列。换句话说,将planid中的每个值看作“桶”,如果我要从planid中的每个 “桶”中抽取x的值,我想要所有可能的组合。 (a1,b1,c1),(a1,b2,c1),(a1,b1,c2),(a1,b2,c2),(a2,b1,c1) ,(a2,b2,c1),(a2,b1,c2),(a2,b2,c2)}。

但是,我希望我的结果数据帧为三列,planid,x和另一列,可能名称为permutation_counter。最终数据帧具有标记为permutation_counter的所有不同排列。换句话说,我希望我的最终数据框看起来像

 planid x permutation_counter 
    0 A  a1  1 
    1 B  b1  1 
    2 C  c1  1 
    3 A  a1  2 
    4 B  b2  2 
    5 C  c1  2 
    6 A  a1  3 
    7 B  b1  3 
    8 C  c2  3 
    9 A  a1  4 
    10 B  b2  4 
    11 C  c2  4 
    12 A  a2  5 
    13 B  b1  5 
    14 C  c1  5 
    15 A  a2  6 
    16 B  b2  6 
    17 C  c1  6 
    18 A  a2  7 
    19 B  b1  7 
    20 C  c2  7 
    21 A  a2  8 
    22 B  b2  8 
    23 C  c2  8 

任何帮助将不胜感激!

回答

2

我试图将尽可能多的步骤链接在一起。打破他们,看看每一步操作:)

df2 = pd.DataFrame(index=pd.MultiIndex.from_product([subdf['x'] for p, subdf in df.groupby('planid')], names=df.planid.unique())).reset_index().stack().reset_index() 

df2.columns = ['permutation_counter', 'planid', 'x'] 
df2['permutation_counter'] += 1 

print df2[['planid', 'x', 'permutation_counter']] 

    planid x permutation_counter 
0  A a1     1 
1  B b1     1 
2  C c1     1 
3  A a1     2 
4  B b1     2 
5  C c2     2 
6  A a1     3 
7  B b2     3 
8  C c1     3 
9  A a1     4 
10  B b2     4 
11  C c2     4 
12  A a2     5 
13  B b1     5 
14  C c1     5 
15  A a2     6 
16  B b1     6 
17  C c2     6 
18  A a2     7 
19  B b2     7 
20  C c1     7 
21  A a2     8 
22  B b2     8 
23  C c2     8 
2

@ Happy001通过几分钟的打我,但我会继续前进,反正发布此,因为我认为这是一个比较容易遵循:

import numpy as np 
import pandas as pd 
import itertools 

x = list(itertools.product(['a1','b2'],['b1','b2'],['c1','c2'])) 
x = list(itertools.chain(*x)) 
df = pd.DataFrame({ 'planid' : np.tile(list('ABC'), 8), 
        'x'  : x, 
        'p_count' : np.repeat(range(1,9), 3) }) 

结果:

p_count planid x 
0   1  A a1 
1   1  B b1 
2   1  C c1 
3   2  A a1 
4   2  B b1 
5   2  C c2 

... 

21  8  A b2 
22  8  B b2 
23  8  C c2 
+0

嘿强尼。这有点容易遵循,但在我的实际情况中,我确实有很多值,并且不能明确指定'a1','b2'等。 – Vincent

+0

尽管感谢您的帮助! – Vincent

+0

@Vincent - 当然,希望它有帮助。我怀疑这可能是一般化来处理您的情况,但我不清楚您的样本数据将如何映射到您的实际数据。 Happy001以一种聪明的方式处理了这个问题(对from_product使用groupby),希望这对你的真实数据也有效,但我不确定它会如何。实际上,我们的答案基本上都是一样的,所以你可以混合和匹配每个片段。 – JohnE

相关问题