根据数据框中其他列的值,将列表JSON对象插入行。

4
我有一个带有以下列的数据框:
ID A1 B1 C1 A2 B2 C2 A3 B3 C3
AA  1  3  6           4  0  6 
BB  5  5  4  6  7  9 
CC  5  5  5           

我想创建一个名为 Z 的新列,它将每一行分组成一个 JSON 记录列表,并将该列重命名为它们的键。构建完 JSON 列后,我想删除所有列,只保留 Z 和 ID 列。
期望的输出如下:
ID Z
AA [{"A":1, "B":3,"C":6},{"A":4, "B":0,"C":6}]
BB [{"A":5, "B":5,"C":4},{"A":6, "B":7,"C":9}]
CC [{"A":5, "B":5,"C":5}]

这是我的目前尝试:

df2 = df.groupby(['ID']).apply(lambda x: x[['A1', 'B1', 'C1',
                                            'A2', 'B2', 'C2', 'A3', 'B3', 'C3']].to_dict('records')).to_frame('Z').reset_index()

问题在于我无法重命名列,使得只保留字母而去除数字,就像上面的例子一样。运行上述代码还没有把每组3个元素分开成一个对象,而是创建了两个列表对象。如果可能的话,我希望用Pandas实现这个功能。如有任何指导,将不胜感激。
4个回答

1

Pandas解决方案

通过在正则表达式分隔符周围拆分和扩展,将列转换为MultiIndex,然后stack数据框以将数据框转换为多索引序列,然后在level=0上对数据框进行分组并应用to_dict函数来创建每个ID的记录。

s = df.set_index('ID')
s.columns = s.columns.str.split(r'(?=\d+$)', expand=True)
s.stack().groupby(level=0).apply(pd.DataFrame.to_dict, 'records').reset_index(name='Z')

结果

   ID                                                                 Z
0  AA  [{'A': 1.0, 'B': 3.0, 'C': 6.0}, {'A': 4.0, 'B': 0.0, 'C': 6.0}]
1  BB  [{'A': 5.0, 'B': 5.0, 'C': 4.0}, {'A': 6.0, 'B': 7.0, 'C': 9.0}]
2  CC                                  [{'A': 5.0, 'B': 5.0, 'C': 5.0}]

你好,感谢您抽出时间回答我的问题。不幸的是,当我运行您提供的代码时,我得到的结果与您的不同;以下是我使用相同的数据和代码输出的结果。 A B C A B C A B2. C 1 1 1 2 2 2 3 1 3 ID
AA 1 3 6 4 0 6 BB 5 5 4 6 7 9
CC 5 5 5 `最后有一个随机的反引号,请让我知道您对输出问题有什么建议。
- ApacheOne
{'ID': {0: 'AA', 1: 'BB', 2: 'CC'}, 'A1': {0: 1, 1: 5, 2: 5}, 'B1': {0: 3, 1: 5, 2: 5}, 'C1': {0: 6, 1: 4, 2: 5}, 'A2': {0: nan, 1: 6.0, 2: nan}, 'B2': {0: nan, 1: 7.0, 2: nan}, 'C2': {0: nan, 1: 9.0, 2: nan}, 'A3': {0: 4.0, 1: nan, 2: nan}, 'B2.1': {0: 0.0, 1: nan, 2: nan}, 'C3': {0: 6.0, 1: nan, 2: nan}} - ApacheOne
@ApacheOne 在提供的示例中,我看到您有一个名为“B2.1”的列,它与其他列的标准格式不同? - Shubham Sharma
@ApacheOne 对于这个例子,我认为这里提供的解决方案应该可以很好地工作。 - Shubham Sharma
我会再试一次。感谢您的耐心。 - ApacheOne
显示剩余3条评论

0

你尝试逐行检查了吗?我对pandas和python不是很擅长,但我有这段代码。希望它能对你有用。

toAdd = []
for row in dataset.values:
    toAddLine = {}
    i = 0
    for data in row:
        
        if data is not None:
            toAddLine["New Column Name "+dataset.columns[i]] = data
        i = i +1 
            
    toAdd.append(toAddLine)
dataset['Z'] = toAdd
dataset['Z']

0
# create a columns name map for chang related column
columns = dataset.columns
columns_map = {}
for i in columns:
    columns_map[i] = f"new {i}"

def change_row_to_json(row):
    new_dict = {}
    for index, value in enumerate(row):
        new_dict[columns_map[columns[index]]] = value
    return json.dumps(new_dict, indent = 4)

dataset.loc[:,'Z'] = dataset.apply(change_row_to_json, axis=1)
dataset= dataset[["ID", "Z"]]

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

0

我只是在Subham的代码上添加了几行,然后它就对我起作用了。

import pandas as pd 
from numpy import nan
data = pd.DataFrame({'ID': {0: 'AA', 1: 'BB', 2: 'CC'}, 'A1': {0: 1, 1: 5, 2: 5}, 'B1': {0: 3, 1: 5, 2: 5}, 'C1': {0: 6, 1: 4, 2: 5}, 'A2': {0: nan, 1: 6.0, 2: nan}, 'B2': {0: nan, 1: 7.0, 2: nan}, 'C2': {0: nan, 1: 9.0, 2: nan}, 'A3': {0: 4.0, 1: nan, 2: nan}, 'B3': {0: 0.0, 1: nan, 2: nan}, 'C3': {0: 6.0, 1: nan, 2: nan}} )
data

enter image description here

data.index = data.ID
data.drop(columns=['ID'],inplace=True)
data
data.columns = data.columns.str.split(r'(?=\d+$)', expand=True)

enter image description here

d = data.stack().groupby(level=0).apply(pd.DataFrame.to_dict, 'records').reset_index(name='Z')
d.index = d.ID
d.drop(columns=['ID'],inplace=True)
d.to_dict()['Z']

enter image description here

现在我们可以看到,由于@shubham Sharma的回答,我们得到了期望的输出。我认为这可能会有所帮助。

嗨,Noman,感谢你的澄清。我犯了一个小错误,没有包括一些额外的列,这些列是数据框的一部分,我认为需要它们。这是我拥有的DF: {'ID': {0: 'AA', 1: 'BB', 2: 'CC'}, 'Y': {0: 'ABC', 1: 'GHZ', 2: 'YUR'}, 'X': {0: 'XZY', 1: 'NOY', 2: 'YTN'}, 'A1': {0: 1, 1: 5, 2: 5}, 'B1': {0: 3, 1: 5, 2: 5}, 'C1': {0: 6, 1: 4, 2: 5}, 'A2': {0: nan, 1: 6.0, 2: nan}, 'B2': {0: nan, 1: 7.0, 2: nan}, 'C2': {0: nan, 1: 9.0, 2: nan}, 'A3': {0: 4.0, 1: nan, 2: nan}, 'B3': {0: 0.0, 1: nan, 2: nan}, 'C3': {0: 6.0, 1: nan, 2: nan}} - ApacheOne
你会注意到我现在有了Z列和X列。我想将它们包含在输出结果中。输出结果应该与已有的输出结果相同,包括列ID、Y、X和Z。 - ApacheOne
嘿,@ApacheOne,你能否提供一下输出的具体样式吗? - Noman
我学会了如何将我的数据与你最后的编辑结合使用,并且我得到了想要的工作输出。我需要给你们两个人中的一个人以功劳,但我不确定该如何做,因为你们都提供了帮助。 - ApacheOne
很高兴听到你得到了工作输出。 - Noman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接