如果列名匹配,则将dataframe列值更改为行

2024-06-26 14:24:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用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异常


Tags: 数据对象namecomidjsonemail规范化
2条回答

您只能选择一列,但由于选择了重复的列名称,所以所有列都具有相同的标签,然后转换为1dnumpy数组并传递给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

另一个想法是通过^{}在列中创建MultiIndex,并通过^{}重塑:

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

如果您确实知道这样的数据结构是一致的,那么只需按索引对数据进行切片,然后将它们连接起来:

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)])

相关问题 更多 >