【问题标题】:All possible permutations columns Pandas Dataframe within the same column同一列中所有可能的排列列 Pandas Dataframe
【发布时间】:2016-02-20 02:12:26
【问题描述】:

我在使用 Postgres SQL 时遇到过类似的问题,但我认为这种任务在 Postgres 中确实很难完成,我认为 python/pandas 会使这变得容易得多,尽管我仍然想不出来解决方案。

我现在有一个看起来像这样的 Pandas 数据框:

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

任何帮助将不胜感激!

【问题讨论】:

    标签: python pandas permutation


    【解决方案1】:

    我试图将尽可能多的步骤链接在一起。分解它们以查看每个步骤的作用:)

    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
      

      【讨论】:

      • 嘿,JohnE。这更容易理解,但在我的实际情况下,我实际上有很多值,并且无法明确指定“a1”、“b2”等。
      • 感谢您的帮助!
      • @Vincent -- 当然,希望对您有所帮助。我怀疑它可以概括为处理您的情况,但对我来说,您的样本数据将如何映射到您的实际数据并不明显。 Happy001 以一种巧妙的方式处理了这个问题(将 groupby 与 from_product 一起使用),希望这也适用于您的真实数据,但我不确定它是否会起作用。实际上,我们的两个答案基本上都做同样的事情,所以你当然可以混合和匹配每个答案。
      猜你喜欢
      • 2017-06-12
      • 1970-01-01
      • 2012-07-11
      • 2011-02-20
      • 2022-11-06
      • 1970-01-01
      • 2020-04-29
      • 1970-01-01
      相关资源
      最近更新 更多