重塑 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_num
s 并且只是
假设 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
我有一个如下所示的数据框:
>>> 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_num
s 并且只是
假设 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