所有可能的排列列Pandas Dataframe在同一列中

时间:2016-02-20 02:12:26

标签: python pandas permutation

我使用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中的每个值都视为“桶”,如果我要从每个x中绘制值,我想要所有可能的组合 planid中的“桶”。在这个特定的例子中,总共有8个排列{(a1,b1,c1),(a1,b2,c1),(a1,b1,c2),(a1,b2,c2),(a2,b1,c1) ,(a2,b2,c1),(a2,b1,c2),(a2,b2,c2)}。

但是,我希望结果数据框为三列,planidx和另一列,可能名为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 个答案:

答案 0 :(得分: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

答案 1 :(得分: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