我正在尝试堆叠、熔化、grouby 或重塑 Pandas DataFrame
I am trying to Stack, Melt, grouby or reshape a Pandas DataFrame
我正在尝试重塑下面的数据框(从 .csv 导入),将东距、北距和节点名称值保持在同一行,但所有内容 'stacked' 都在 4 列中。因此,我希望 V0e、V0n 和 Vd 列中的数据位于 S0_Pe、S0_Pn 和 S0_Pd 列中的数据之上。实际上有 8 组这样的 easting/northing/node 三重奏。
我是否需要将 V0e、V0n、S0_Pe 和 S0_Pn 重命名为 'Easting' 和 'Northing' 以及 Vd & S0_Pd 为 'Node'?
我已经尝试过 grouby、stack 和 melt,但要么所有内容都变成两列('shot' 和其他所有内容),要么无法按照我的意愿进行分组。
我还查看了 MultiIndex,节点位于 easting/northing 对之上的级别,但我未能将其应用于从我的 .csv 文件加载的现有 df。
Index shot V0e V0n Vd S0_Pe S0_Pn S0_Pd
0 1001 530811.1 6764623.3 Vd nan nan S0_Pd
1 1002 530808.8 6764617.4 Vd 530771.3 6764510.4 S0_Pd
2 1003 530806.6 6764611.4 Vd nan nan S0_Pd
3 1004 530804.2 6764605.8 Vd 530765.6 6764499.1 S0_Pd
我不介意它看起来像这样:
Index shot V0e V0n Vd
0 1001 530811.1 6764623.3 Vd
1 1002 530808.8 6764617.4 Vd
2 1003 530806.6 6764611.4 Vd
3 1004 530804.2 6764605.8 Vd
4 1001 nan nan S0_Pd
5 1002 530771.3 6764510.4 S0_Pd
6 1003 nan nan S0_Pd
7 1004 530765.6 6764499.1 S0_Pd
或者这个,我只需要坐标对和节点一起移动:
Index shot V0e V0n Vd
0 1001 530811.1 6764623.3 Vd
1 1001 nan nan S0_Pd
2 1002 530808.8 6764617.4 Vd
3 1002 530771.3 6764510.4 S0_Pd
4 1003 530806.6 6764611.4 Vd
5 1003 nan nan S0_Pd
6 1004 530804.2 6764605.8 Vd
7 1004 530765.6 6764499.1 S0_Pd
您可以这样做 pd.wide_to_long 并重命名一个小列以标准化:
df_rc = df.rename(columns={'V0e':'V0e:Vd',
'V0n':'V0n:Vd',
'S0_Pe':'V0e:S0_Pd',
'S0_Pn':'V0n:S0_Pd'})
df_rc = df_rc.drop(['Vd', 'S0_Pd'], axis=1)
df_out = pd.wide_to_long(df_rc,
['V0e', 'V0n'],
['Index', 'shot'],
'Vd',
':',
'.*')\
.reset_index()
输出:
Index shot Vd V0e V0n
0 0 1001 Vd 530811.1 6764623.3
1 0 1001 S0_Pd NaN NaN
2 1 1002 Vd 530808.8 6764617.4
3 1 1002 S0_Pd 530771.3 6764510.4
4 2 1003 Vd 530806.6 6764611.4
5 2 1003 S0_Pd NaN NaN
6 3 1004 Vd 530804.2 6764605.8
7 3 1004 S0_Pd 530765.6 6764499.1
您可以使用经常被遗忘的 pd.lreshape
来做到这一点:
此函数是 pd.wide_to_long
的通用版本,您可以在其中传递 {new_column name: [*columns to vertically stack]}
的字典。然后melt
编辑此字典中任何未指定的列以适合输出。
import pandas as pd
out = pd.lreshape(
df,
{'V0e': ['V0e', 'S0_Pe'],
'V0n': ['V0n', 'S0_Pn'],
'Vd': ['Vd', 'S0_Pd']},
dropna=False
)
print(out)
Index shot V0e V0n Vd
0 0 1001 530811.1 6764623.3 Vd
1 1 1002 530808.8 6764617.4 Vd
2 2 1003 530806.6 6764611.4 Vd
3 3 1004 530804.2 6764605.8 Vd
4 0 1001 NaN NaN S0_Pd
5 1 1002 530771.3 6764510.4 S0_Pd
6 2 1003 NaN NaN S0_Pd
7 3 1004 530765.6 6764499.1 S0_Pd
一个有效的选择是使用 pivot_longer from pyjanitor 转换为长格式,将新列 headers 的列表传递给 names_to
,并在 names_pattern
中使用相应的正则表达式模式:
# pip install pyjanitor
import pandas as pd
import janitor
df.pivot_longer(index = 'shot',
names_to = ('V0e', 'V0n', 'Vd'),
names_pattern = ('e$', 'n$', 'd$'),
sort_by_appearance = True)
shot V0e V0n Vd
0 1001 530811.1 6764623.3 Vd
1 1001 NaN NaN S0_Pd
2 1002 530808.8 6764617.4 Vd
3 1002 530771.3 6764510.4 S0_Pd
4 1003 530806.6 6764611.4 Vd
5 1003 NaN NaN S0_Pd
6 1004 530804.2 6764605.8 Vd
7 1004 530765.6 6764499.1 S0_Pd
我正在尝试重塑下面的数据框(从 .csv 导入),将东距、北距和节点名称值保持在同一行,但所有内容 'stacked' 都在 4 列中。因此,我希望 V0e、V0n 和 Vd 列中的数据位于 S0_Pe、S0_Pn 和 S0_Pd 列中的数据之上。实际上有 8 组这样的 easting/northing/node 三重奏。
我是否需要将 V0e、V0n、S0_Pe 和 S0_Pn 重命名为 'Easting' 和 'Northing' 以及 Vd & S0_Pd 为 'Node'?
我已经尝试过 grouby、stack 和 melt,但要么所有内容都变成两列('shot' 和其他所有内容),要么无法按照我的意愿进行分组。
我还查看了 MultiIndex,节点位于 easting/northing 对之上的级别,但我未能将其应用于从我的 .csv 文件加载的现有 df。
Index shot V0e V0n Vd S0_Pe S0_Pn S0_Pd
0 1001 530811.1 6764623.3 Vd nan nan S0_Pd
1 1002 530808.8 6764617.4 Vd 530771.3 6764510.4 S0_Pd
2 1003 530806.6 6764611.4 Vd nan nan S0_Pd
3 1004 530804.2 6764605.8 Vd 530765.6 6764499.1 S0_Pd
我不介意它看起来像这样:
Index shot V0e V0n Vd
0 1001 530811.1 6764623.3 Vd
1 1002 530808.8 6764617.4 Vd
2 1003 530806.6 6764611.4 Vd
3 1004 530804.2 6764605.8 Vd
4 1001 nan nan S0_Pd
5 1002 530771.3 6764510.4 S0_Pd
6 1003 nan nan S0_Pd
7 1004 530765.6 6764499.1 S0_Pd
或者这个,我只需要坐标对和节点一起移动:
Index shot V0e V0n Vd
0 1001 530811.1 6764623.3 Vd
1 1001 nan nan S0_Pd
2 1002 530808.8 6764617.4 Vd
3 1002 530771.3 6764510.4 S0_Pd
4 1003 530806.6 6764611.4 Vd
5 1003 nan nan S0_Pd
6 1004 530804.2 6764605.8 Vd
7 1004 530765.6 6764499.1 S0_Pd
您可以这样做 pd.wide_to_long 并重命名一个小列以标准化:
df_rc = df.rename(columns={'V0e':'V0e:Vd',
'V0n':'V0n:Vd',
'S0_Pe':'V0e:S0_Pd',
'S0_Pn':'V0n:S0_Pd'})
df_rc = df_rc.drop(['Vd', 'S0_Pd'], axis=1)
df_out = pd.wide_to_long(df_rc,
['V0e', 'V0n'],
['Index', 'shot'],
'Vd',
':',
'.*')\
.reset_index()
输出:
Index shot Vd V0e V0n
0 0 1001 Vd 530811.1 6764623.3
1 0 1001 S0_Pd NaN NaN
2 1 1002 Vd 530808.8 6764617.4
3 1 1002 S0_Pd 530771.3 6764510.4
4 2 1003 Vd 530806.6 6764611.4
5 2 1003 S0_Pd NaN NaN
6 3 1004 Vd 530804.2 6764605.8
7 3 1004 S0_Pd 530765.6 6764499.1
您可以使用经常被遗忘的 pd.lreshape
来做到这一点:
此函数是 pd.wide_to_long
的通用版本,您可以在其中传递 {new_column name: [*columns to vertically stack]}
的字典。然后melt
编辑此字典中任何未指定的列以适合输出。
import pandas as pd
out = pd.lreshape(
df,
{'V0e': ['V0e', 'S0_Pe'],
'V0n': ['V0n', 'S0_Pn'],
'Vd': ['Vd', 'S0_Pd']},
dropna=False
)
print(out)
Index shot V0e V0n Vd
0 0 1001 530811.1 6764623.3 Vd
1 1 1002 530808.8 6764617.4 Vd
2 2 1003 530806.6 6764611.4 Vd
3 3 1004 530804.2 6764605.8 Vd
4 0 1001 NaN NaN S0_Pd
5 1 1002 530771.3 6764510.4 S0_Pd
6 2 1003 NaN NaN S0_Pd
7 3 1004 530765.6 6764499.1 S0_Pd
一个有效的选择是使用 pivot_longer from pyjanitor 转换为长格式,将新列 headers 的列表传递给 names_to
,并在 names_pattern
中使用相应的正则表达式模式:
# pip install pyjanitor
import pandas as pd
import janitor
df.pivot_longer(index = 'shot',
names_to = ('V0e', 'V0n', 'Vd'),
names_pattern = ('e$', 'n$', 'd$'),
sort_by_appearance = True)
shot V0e V0n Vd
0 1001 530811.1 6764623.3 Vd
1 1001 NaN NaN S0_Pd
2 1002 530808.8 6764617.4 Vd
3 1002 530771.3 6764510.4 S0_Pd
4 1003 530806.6 6764611.4 Vd
5 1003 NaN NaN S0_Pd
6 1004 530804.2 6764605.8 Vd
7 1004 530765.6 6764499.1 S0_Pd