将数据集从宽变长 pandas
Transform a dataset from wide to long pandas
我对数据集从宽到长的转换有点问题。我尝试使用 melt,但没有得到好的结果。我希望有人能帮助我。数据集如下:
pd.DataFrame({'id': [0, 1, 2, 3, 4, 5],
'type': ['a', 'b', 'c', 'd', 'e', 'f'],
'rank': ['alpha', 'beta', 'gamma', 'epsilon', 'phi', 'ro'],
'type.1': ['d', 'g', 'z', 'a', 'nan', 'nan'],
'rank.1': ['phi', 'sigma', 'gamma', 'lambda', 'nan', 'nan'],
'type.2': ['nan', 'nan', 'j', 'r', 'nan', 'nan'],
'rank.2': ['nan', 'nan', 'eta', 'theta', 'nan', 'nan']})
我需要这样的数据集:
pd.DataFrame({'id': [0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5],
'type': ['a', 'd', 'b', 'g', 'c', 'z', 'j', 'd', 'a', 'r', 'e', 'f'],
'rank': ['alpha', 'phi', 'beta', 'sigma', 'gamma', 'gamma', 'eta', 'epsilon', 'lambda', 'theta', 'phi', 'ro']})
有人可以帮我吗?非常感谢
使用wide_to_long
:
# normalize the `type` and `rank` columns so they have the same format as others
df = df.rename(columns={'type': 'type.0', 'rank': 'rank.0'})
(pd.wide_to_long(df, stubnames=['type', 'rank'], i='id', j='var', sep='.')
[lambda x: (x['type'] != 'nan') | (x['rank'] != 'nan')].reset_index())
id var type rank
0 0 0 a alpha
1 1 0 b beta
2 2 0 c gamma
3 3 0 d epsilon
4 4 0 e phi
5 5 0 f ro
6 0 1 d phi
7 1 1 g sigma
8 2 1 z gamma
9 3 1 a lambda
10 2 2 j eta
11 3 2 r theta
如果不需要,您可以删除 var
列。
一个选项是pivot_longer from pyjanitor,它抽象了整形过程:
# pip install janitor
import janitor
(df
.pivot_longer(
index = 'id',
names_to = ['type', 'rank'],
names_pattern = ['type', 'rank'],
sort_by_appearance = True)
.loc[lambda df: ~df.eq('nan').any(1)]
)
id type rank
0 0 a alpha
1 0 d phi
3 1 b beta
4 1 g sigma
6 2 c gamma
7 2 z gamma
8 2 j eta
9 3 d epsilon
10 3 a lambda
11 3 r theta
12 4 e phi
15 5 f ro
此特定重塑的想法是 names_pattern
中的每个正则表达式用于将匹配列与 names_to
中的配对名称配对。
我对数据集从宽到长的转换有点问题。我尝试使用 melt,但没有得到好的结果。我希望有人能帮助我。数据集如下:
pd.DataFrame({'id': [0, 1, 2, 3, 4, 5],
'type': ['a', 'b', 'c', 'd', 'e', 'f'],
'rank': ['alpha', 'beta', 'gamma', 'epsilon', 'phi', 'ro'],
'type.1': ['d', 'g', 'z', 'a', 'nan', 'nan'],
'rank.1': ['phi', 'sigma', 'gamma', 'lambda', 'nan', 'nan'],
'type.2': ['nan', 'nan', 'j', 'r', 'nan', 'nan'],
'rank.2': ['nan', 'nan', 'eta', 'theta', 'nan', 'nan']})
我需要这样的数据集:
pd.DataFrame({'id': [0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5],
'type': ['a', 'd', 'b', 'g', 'c', 'z', 'j', 'd', 'a', 'r', 'e', 'f'],
'rank': ['alpha', 'phi', 'beta', 'sigma', 'gamma', 'gamma', 'eta', 'epsilon', 'lambda', 'theta', 'phi', 'ro']})
有人可以帮我吗?非常感谢
使用wide_to_long
:
# normalize the `type` and `rank` columns so they have the same format as others
df = df.rename(columns={'type': 'type.0', 'rank': 'rank.0'})
(pd.wide_to_long(df, stubnames=['type', 'rank'], i='id', j='var', sep='.')
[lambda x: (x['type'] != 'nan') | (x['rank'] != 'nan')].reset_index())
id var type rank
0 0 0 a alpha
1 1 0 b beta
2 2 0 c gamma
3 3 0 d epsilon
4 4 0 e phi
5 5 0 f ro
6 0 1 d phi
7 1 1 g sigma
8 2 1 z gamma
9 3 1 a lambda
10 2 2 j eta
11 3 2 r theta
如果不需要,您可以删除 var
列。
一个选项是pivot_longer from pyjanitor,它抽象了整形过程:
# pip install janitor
import janitor
(df
.pivot_longer(
index = 'id',
names_to = ['type', 'rank'],
names_pattern = ['type', 'rank'],
sort_by_appearance = True)
.loc[lambda df: ~df.eq('nan').any(1)]
)
id type rank
0 0 a alpha
1 0 d phi
3 1 b beta
4 1 g sigma
6 2 c gamma
7 2 z gamma
8 2 j eta
9 3 d epsilon
10 3 a lambda
11 3 r theta
12 4 e phi
15 5 f ro
此特定重塑的想法是 names_pattern
中的每个正则表达式用于将匹配列与 names_to
中的配对名称配对。