如果列名称匹配,则将数据框列值更改为行

时间:2020-10-20 04:48:19

标签: python json pandas dataframe

我使用json_normalize将json对象标准化为一个数据帧,它看起来像这样:

ID Name     Email_id      ID Name Email_id     ID Name  Email_id
1   A      A@gmail.com     2  B    B@gmail.com  3  C    C@gmail.com

我想将列值转换为这样的行:-

ID   Name   Email_id
1     A      A@gmil.com
2     B      B@gmail.com
3     C      C@gmail.com

但是我无法做到这一点。我尝试了pd.melt(),但是却给了Data must be 1-dimensional个例外。

2 个答案:

答案 0 :(得分:1)

您只能选择一列,但是由于重复的列名会被选中具有相同标签的所有列,然后转换为1d numpy数组并传递给DataFrame构造函数:

print (df['ID'])
   ID  ID  ID
0   1   2   3

df = pd.DataFrame({'ID': df['ID'].to_numpy().ravel(),
                   'Name': df['Name'].to_numpy().ravel(),
                   'Email_id': df['Email_id'].to_numpy().ravel()})
print (df)
   ID Name     Email_id
0   1    A  A@gmail.com
1   2    B  B@gmail.com
2   3    C  C@gmail.com

另一个想法是在GroupBy.cumcount的列中创建MultiIndex并通过DataFrame.stack进行整形:

s = df.columns.to_series()

df.columns = [s, s.groupby(s).cumcount()]
print (df)

  ID Name     Email_id ID Name     Email_id ID Name     Email_id
   0    0            0  1    1            1  2    2            2
0  1    A  A@gmail.com  2    B  B@gmail.com  3    C  C@gmail.com

df = df.stack().reset_index(drop=True)
print (df)
      Email_id  ID Name
0  A@gmail.com   1    A
1  B@gmail.com   2    B
2  C@gmail.com   3    C

答案 1 :(得分:1)

如果您确实知道这种数据结构是一致的,则可以按索引对数据进行切片,然后将它们连接起来:

pd.concat([df.iloc[:, i:i+3] for i in range(0, df.shape[1], 3)])

要确保获取列ID:

import numpy as np

# Get the target indexes
idx = np.arange(df.shape[1])[df.columns=='ID']
idx = np.append(idx, df.shape[1])

# Slice and concatenate data
pd.concat([df.iloc[:, idx[i]:idx[i+1]] for i in range(len(idx)-1)])