在熊猫中执行几乎不完整的数据透视表操作

时间:2018-09-10 01:38:08

标签: python python-3.x pandas data-manipulation

我有一个如下数据框:

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 个答案:

答案 0 :(得分:2)

一种可能是这样:

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”)上对齐。一种清理工作,我们就完成了。