重塑 pandas 数据框,将现有列的值转换为忽略索引的新的较低级别列

Reshaping pandas dataframe, converting values of an existing column into new lower level columns with index ignored

我有一个如下所示的数据框:

>>> x[x.site_num<3]
Out[44]: 
       6890011  site_num
item                    
0     3.226545         0
1     3.226698         1
2     3.221418         2
12    3.231642         0
13    3.226331         1
14    3.221449         2
24    3.231123         0
25    3.226454         1
26    3.226240         2
36    3.226484         0
37    3.226240         1
38    3.221571         2
48    3.226118         0
49    3.226331         1
50    3.221021         2

我正在努力让它看起来像这样:

       6890011
             0         1         2           
item
0     3.226545  3.226698  3.221418
1     3.231642  3.226331  3.221449
2     3.231123  3.226454  3.226240
3     3.226484  3.226240  3.221571
4     3.226118  3.226331  3.221021

我试过这样使用数据透视表:

x.pivot(columns='site_num', values=6890011)

但它似乎不允许我跳过 'index' 部分。

我一直在尝试使用 set_index()、stack() 和 unstack(),但我就是无法获得想要的结果。使用 groupby() 将迫使我进一步处理数据(求和、计数等),而不仅仅是列出值。你会怎么做?

数据框中的 item 索引是一个误导,因为输入中的 item 与所需输出中的 item 无关.使枢轴工作所需的 item 值如下所示:

In [67]: x.reset_index(drop=True)
Out[67]: 
     6890011  site_num  item
0   3.226545         0     0
1   3.226698         1     0
2   3.221418         2     0
3   3.231642         0     1
4   3.226331         1     1
5   3.221449         2     1
6   3.231123         0     2
7   3.226454         1     2
8   3.226240         2     2
9   3.226484         0     3
10  3.226240         1     3
11  3.221571         2     3
12  3.226118         0     4
13  3.226331         1     4
14  3.221021         2     4

您可以使用 groupby/cumcount 创建此 item 列:

x['item'] = x.groupby(['site_num']).cumcount()

一旦您在 item 列中获得正确的值,pivot 调用自然会发生:

In [63]: x['item'] = x.groupby(['site_num']).cumcount()

In [64]: x.pivot(columns='site_num', index='item')
Out[64]: 
           6890011                    
site_num         0         1         2
item                                  
0         3.226545  3.226698  3.221418
1         3.231642  3.226331  3.221449
2         3.231123  3.226454  3.226240
3         3.226484  3.226240  3.221571
4         3.226118  3.226331  3.221021

实现此结果的另一种方法是从 x['6890011'] 中提取 NumPy 数组并使用 reshape:

In [78]: pd.DataFrame(x['6890011'].values.reshape(-1, 3))
Out[78]: 
          0         1         2
0  3.226545  3.226698  3.221418
1  3.231642  3.226331  3.221449
2  3.231123  3.226454  3.226240
3  3.226484  3.226240  3.221571
4  3.226118  3.226331  3.221021

这非常快但不够稳健,因为它忽略了实际的 site_nums 并且只是 假设 site_num 循环通过 0,1,2 并且 len(x['site_num']) 是 3 的倍数。即使 len(x['site_num']) 不是 3 的倍数,groupby/cumcount/pivot 方法仍然有效3 根据需要添加 NaN。

这是另一个尝试(不一定很漂亮):

>>> grouped = x.groupby('site_num')['6890011']
>>> pd.DataFrame([grouped.get_group(group).values for group in grouped.groups]).T
          0         1         2
0  3.226545  3.226698  3.221418
1  3.231642  3.226331  3.221449
2  3.231123  3.226454  3.226240
3  3.226484  3.226240  3.221571
4  3.226118  3.226331  3.221021