我无法将下面的数据框重整为长格式:
df = pd.DataFrame({'id': [66602088802, 85002620928],
't1': ['car', 'house'],
't1_pct': [0.46, 0.51],
't1_valid': [True, True],
't2': ['bike', 'car'],
't2_pct': [0.15, 0.07],
't2_valid': [True, True],
't3': ['car', 'toy'],
't3_pct': [0.06, 0.07],
't3_valid': [False, False]})
id t1 t1_pct t1_valid t2 t2_pct t2_valid t3 t3_pct t3_valid
0 66602088802 car 0.46 True bike 0.15 True car 0.06 False
1 85002620928 house 0.51 True car 0.07 True toy 0.07 False
我想要的结果如下。我尝试使用pandas.wide_to_long()
,但到目前为止还没有运气。预先感谢。
id test value pct valid
66602088802 1 car 0.46 True
85002620928 1 house 0.51 True
66602088802 2 bike 0.15 True
85002620928 2 car 0.07 True
66602088802 3 car 0.06 False
85002620928 3 toy 0.07 False
谢谢。
熊猫0.23.4
python 3.7.1
答案 0 :(得分:2)
我认为wide_to_long不能重塑您所需的形状,您可以使用melt
进行检查
s=df.melt('id')
s=pd.concat([s,s.variable.str.split('_',expand=True)],1).fillna('value')
s.set_index(['id',0,1]).value.unstack().reset_index().rename(columns={0:'text'})
1 id text pct valid value
0 66602088802 t1 0.46 True car
1 66602088802 t2 0.15 True bike
2 66602088802 t3 0.06 False car
3 85002620928 t1 0.51 True house
4 85002620928 t2 0.07 True car
5 85002620928 t3 0.07 False toy
答案 1 :(得分:1)
您可以使用wide_to_long
;问题只是您的列名需要稍作更改,以便存根名为['pct', 'valid', 'value']
,而不是t#
。
import pandas as pd
import numpy as np
# Reverse order of words around '_'
df.columns = ['_'.join(x.split('_')[::-1]) for x in df.columns]
# Add prefix for other stubs
df = df.rename(columns= dict((f't{i}', f'value_t{i}') for i in np.arange(1,4,1)))
pd.wide_to_long(df, stubnames=['pct', 'valid', 'value'],
i='id', j='test', suffix='.*', sep='_').reset_index()
id test pct valid value
0 66602088802 t1 0.46 True car
1 85002620928 t1 0.51 True house
2 66602088802 t2 0.15 True bike
3 85002620928 t2 0.07 True car
4 66602088802 t3 0.06 False car
5 85002620928 t3 0.07 False toy
答案 2 :(得分:1)
这是一个老问题;此答案可能对寻找替代方案的新访问者有所帮助。
这个答案借鉴了@ALollz 在重塑前重命名列的解决方案。
您可以使用 pivot_longer 中的 pyjanitor 函数;目前您必须从 github 安装最新的开发版本:
import re
# install latest dev version
# pip install git+https://github.com/ericmjl/pyjanitor.git
import janitor
(
df.rename(columns=lambda column: f"{column}_value"
if re.match("t\d$", column)
else column)
.pivot_longer(index="id",
names_to=("temp", ".value"),
names_sep="_")
.drop(columns="temp")
)
id value pct valid
0 66602088802 car 0.46 True
1 85002620928 house 0.51 True
2 66602088802 bike 0.15 True
3 85002620928 car 0.07 True
4 66602088802 car 0.06 False
5 85002620928 toy 0.07 False