我有一个单行数据框,如下所示
Num TP1(USD) TP2(USD) TP3(USD) VReal1(USD) VReal2(USD) VReal3(USD) TiV1 (EUR) TiV2 (EUR) TiV3 (EUR) TR TR-Tag
AA-24 0 700 2100 300 1159 2877 30 30 47 10 5
Run Code Online (Sandbox Code Playgroud)
我想要得到一个像下面这样的数据框
ID Price Net Range
1 0 300 30
2 700 1159 30
3 2100 2877 47
Run Code Online (Sandbox Code Playgroud)
这里的逻辑是a. 将有 3 个包含 TP/VR/TV 的列名称。因此,在 ID 中,我们有 1、2 和 3(这些可以通过从列名中提取值或仅使用范围来填充来生成)b。TP1 值进入“价格”列的第一行,TP2 值进入“价格”列的第二行,依此类推 c.VR 和电视也是如此。这些值进入“净值”和“范围”列 d。列“Num”、“TR”和“TR=Tag”与结果无关。
我试过df.filter(regex='TP').stack()。我得到了所有“TP”列,并且可以通过索引([0],[1],[2])访问各个值。我无法将它们全部直接放入一个列中。
我还想知道是否有更简单的方法可以做到这一点。
moz*_*way 12
假设'Num'是唯一标识符,您可以使用pandas.wide_to_long:
pd.wide_to_long(df, stubnames=['TP', 'VR', 'TV'], i='Num', j='ID')
Run Code Online (Sandbox Code Playgroud)
或者,对于更接近您的输出:
out = (pd
.wide_to_long(df, stubnames=['TP', 'VR', 'TV'], i='Num', j='ID')
.reset_index('ID')
.drop(columns=['TR', 'TR-Tag'])
.rename(columns={'TP': 'Price', 'VR': 'Net', 'TV': 'Range'})
)
Run Code Online (Sandbox Code Playgroud)
输出:
ID Price Net Range
Num
AA-24 1 0 300 30
AA-24 2 700 1159 30
AA-24 3 2100 2877 47
Run Code Online (Sandbox Code Playgroud)
out = (pd
.wide_to_long(df.set_axis(df.columns.str.replace(r'\(USD\)$', '', regex=True),
axis=1),
stubnames=['TP', 'VReal', 'TiV'], i='Num', j='ID')
.reset_index('ID')
.drop(columns=['TR', 'TR-Tag'])
.rename(columns={'TP': 'Price', 'VReal': 'Net', 'TiV': 'Range'})
)
Run Code Online (Sandbox Code Playgroud)
输出:
ID Price Net Range
Num
AA-24 1 0 300 30
AA-24 2 700 1159 30
AA-24 3 2100 2877 47
Run Code Online (Sandbox Code Playgroud)
让我们创建一个Multiindex然后使用.stack
df1 = df.filter(regex='TP|VR|TV')
#i couldn't figure out to split by
#word\number without creating an additional whitespace split.
df1.columns = df1.columns\
.str.replace('(\d+)', r' \1' ,regex=True).str.split(' ',expand=True)
#or more succinctly.
df1.columns = pd.MultiIndex.from_frame(df1.columns.str.extract('(\D+)(\d+)'))
print(df1)
TP VR TV
1 2 3 1 2 3 1 2 3
0 0 700 2100 300 1159 2877 30 30 47
Run Code Online (Sandbox Code Playgroud)
df1.stack(1).rename(columns={'TP': 'Price', 'VR': 'Net', 'TV': 'Range'})
Price Range Net
0 1 0 30 300
2 700 30 1159
3 2100 47 2877
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1709 次 |
| 最近记录: |