代码之家  ›  专栏  ›  技术社区  ›  Jack Arnestad

在pandas中执行几乎不完整的透视表操作

  •  2
  • Jack Arnestad  · 技术社区  · 6 年前

    我有一个如下的数据框:

    values = random.sample(range(1, 101), 15)
    
    df = pd.DataFrame({'x': [3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4], 'n': [100, 100, 100, 'reference',  'reference',  'reference', 500, 500, 500, 100, 100, 100,  'reference',  'reference',  'reference'], 'value': values})
    

    中标记为“引用”的值 n 列是引用值,我最终将根据这些值进行绘制。为了帮助实现这一点,我需要创建一个在不同列中包含引用值的数据帧,因此 columns = ['x', 'n', 'value', 'value_reference']

    值引用是的所有值的引用值 n 只要 x 是一样的。因此,我想制作一个如下所示的数据帧:

    desired_df = pd.DataFrame({'x': [3, 3, 3, 3, 3, 3, 4, 4, 4], 'n': [100, 100, 100, 500, 500, 500, 100, 100, 100], 'value': [values[i] for i in [0, 1, 2, 6, 7, 8, 9, 10, 11]], 'value_reference':[values[i] for i in [3, 4, 5, 3, 4, 5, 12, 13, 14]]})
    

    如何做到这一点?

    谢谢, 杰克

    1 回复  |  直到 6 年前
        1
  •  2
  •   DSM    6 年前

    一种方法可能是:

    df["tick"] = df.groupby(["x", "n"]).cumcount()
    
    numbers = df.loc[df["n"] != "reference"]
    ref = df.loc[df["n"] == "reference"]
    ref = ref.drop("n", axis=1).rename(columns={"value": "reference"})
    
    out = numbers.merge(ref).drop("tick", axis=1)
    out = out.sort_values(["x", "n"])
    

    In [282]: out
    Out[282]: 
       x    n  value  reference
    0  3  100      6         67
    2  3  100      9         29
    4  3  100     34         51
    1  3  500     42         67
    3  3  500     36         29
    5  3  500     12         51
    6  4  100     74          5
    7  4  100     48         37
    8  4  100      7         70
    

    一步一步地,首先我们添加一个勾号列,以便知道哪一行值与哪一行引用匹配:

    In [290]: df
    Out[290]: 
        x          n  value  tick
    0   3        100      6     0
    1   3        100      9     1
    2   3        100     34     2
    3   3  reference     67     0
    4   3  reference     29     1
    5   3  reference     51     2
    6   3        500     42     0
    7   3        500     36     1
    8   3        500     12     2
    9   4        100     74     0
    10  4        100     48     1
    11  4        100      7     2
    12  4  reference      5     0
    13  4  reference     37     1
    14  4  reference     70     2
    

    然后我们将表中的值和引用部分分开:

    In [291]: numbers = df.loc[df["n"] != "reference"]
         ...: ref = df.loc[df["n"] == "reference"]
         ...: ref = ref.drop("n", axis=1).rename(columns={"value": "reference"})
         ...: 
         ...: 
    
    In [292]: numbers
    Out[292]: 
        x    n  value  tick
    0   3  100      6     0
    1   3  100      9     1
    2   3  100     34     2
    6   3  500     42     0
    7   3  500     36     1
    8   3  500     12     2
    9   4  100     74     0
    10  4  100     48     1
    11  4  100      7     2
    
    In [293]: ref
    Out[293]: 
        x  reference  tick
    3   3         67     0
    4   3         29     1
    5   3         51     2
    12  4          5     0
    13  4         37     1
    14  4         70     2
    

    然后我们合并,合并将在共享列上对齐,即“x”和“tick”。一种清理东西的方法,我们就完了。