代码之家  ›  专栏  ›  技术社区  ›  filippo

pandas数据帧交错重排序

  •  3
  • filippo  · 技术社区  · 8 年前

    很抱歉标题不太好,可能还有更糟的问题。

    我需要对pandas数据帧执行一个超级简单的操作,但我显然不知道如何调用它,因此找不到要搜索的正确关键字。

    给定一个数据帧

       a   b   c
    0  0  46  14
    1  0   7  14
    2  0  46  19
    3  0   7  19
    4  1  46  14
    5  1   7  14
    6  1  46  19
    7  1   7  19
    

    我需要重新排序行以获取

       a   b   c
    0  0  46  14
    4  1  46  14
    1  0   7  14
    5  1   7  14
    2  0  46  19
    6  1  46  19
    3  0   7  19
    7  1   7  19
    

    另一个简单但可能不那么模棱两可的例子。我想从

       a
    0  0
    1  0
    2  1
    3  1
    4  2
    5  2
    

       a
    0  0
    2  1
    4  2
    1  0
    3  1
    5  2
    

    编辑:关于全貌的一些澄清

    就其价值而言,第一个示例中的数据帧是字典的笛卡尔乘积。

    'a': [0, 1], 'b': array([46,  7]), 'c': array([14, 19])}
    

    [{'a': 0, 'b': 46, 'c': 14},
     {'a': 0, 'b': 7, 'c': 14},
     {'a': 0, 'b': 46, 'c': 19},
     {'a': 0, 'b': 7, 'c': 19},
     {'a': 1, 'b': 46, 'c': 14},
     {'a': 1, 'b': 7, 'c': 14},
     {'a': 1, 'b': 46, 'c': 19},
     {'a': 1, 'b': 7, 'c': 19}]
    

    我需要对它进行排序,以便对于每个参数组合 a 值被分组并一起循环。

    2 回复  |  直到 8 年前
        1
  •  5
  •   DSM    8 年前

    如果要排序以使看到某个值的第0次都是第一次,然后是第1次,依此类推,则可以按感兴趣的列进行分组并对累积计数进行排序:

    In [119]: df.loc[df.groupby("a").cumcount().sort_values(kind='mergesort').index]
    Out[119]: 
       a
    0  0
    2  1
    4  2
    1  0
    3  1
    5  2
    

    有效是因为

    In [120]: df.groupby("a").cumcount()
    Out[120]: 
    0    0
    1    1
    2    0
    3    1
    4    0
    5    1
    dtype: int64
    
    In [121]: df.groupby("a").cumcount().sort_values(kind='mergesort')
    Out[121]: 
    0    0
    2    0
    4    0
    1    1
    3    1
    5    1
    dtype: int64
    

    注意我们正在使用 kind='mergesort' 为了保证稳定性,如果需要,您可以先对原始帧进行排序 [1, 2, 2, 0, 0, 1] -> [0, 0, 1, 1, 2, 2] -> [0, 1, 2, 0, 1, 2] 是的。

        2
  •  1
  •   ALollz    8 年前

    您可以通过创建 DataFrame 一开始就不一样了。而不是仅仅使用 itertools.product ,您可以使用 np.tile np.repeat 去得到你需要的。

    import pandas as pd
    import numpy as np
    
    a = [0, 1] 
    b = np.array([46, 7])
    c = np.array([14, 19])
    
    d = list(zip(np.tile(a, len(b)*len(c)), 
                 np.tile(np.repeat(b, len(a)), len(c)), 
                 np.repeat(c, len(a)*len(b))))
    
    pd.DataFrame(d, columns=['a', 'b', 'c'])
    #   a   b   c
    #0  0  46  14
    #1  1  46  14
    #2  0   7  14
    #3  1   7  14
    #4  0  46  19
    #5  1  46  19
    #6  0   7  19
    #7  1   7  19