将数据集从宽变长 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 中的配对名称配对。