繁体   English   中英

在作为字典列表的 dataframe 列中,如何使用逗号连接值,并将每个嵌套键作为新列?

[英]In a dataframe column that is a list of dictionaries, how to join values with a comma having each nested key as a new column?

我有一个看起来像这样的 dataframe

╔══════╦══════╦══════════════════════════════════╦═══════════════════════╗
║ ID   ║ Name ║ Pets                             ║ CareCenter            ║
╠══════╬══════╬══════════════════════════════════╬═══════════════════════╣
║ 1    ║ John ║ [{'Name':'Alvin','Breed':'Dog'}, ║ {'Name':'PET SHOP 1'} ║
║      ║      ║ {'Name':'Rex','Type':'Cat'}]     ║                       ║
╠══════╬══════╬══════════════════════════════════╬═══════════════════════╣
║ 10   ║ Mary ║ {'Name':'Rose','Type':'Cat'}     ║ {'Name':'PET SHOP 2'} ║
╠══════╬══════╬══════════════════════════════════╬═══════════════════════╣
║ 1234 ║ Joe  ║ {'Name':'Max','Type':'Bird'}     ║ {'Name':'PET SHOP 3'} ║
╚══════╩══════╩══════════════════════════════════╩═══════════════════════╝
  1. 我遍历每一列以检查其类型。

  2. 如果它不是 object(例如字符串、int 等),我将保持不变。

  3. 如果是 object,则:

    3.1)我得到第一行并得到每一列的类型

    3.2)如果该列是 object 和字典(只有一项)我得到这个df

╔══════╦═══════════════════════╗
║ ID   ║ CareCenter            ║
╠══════╬═══════════════════════╣
║ 1    ║ {'Name':'PET SHOP 1'} ║
╠══════╬═══════════════════════╣
║ 10   ║ {'Name':'PET SHOP 2'} ║
╠══════╬═══════════════════════╣
║ 1234 ║ {'Name':'PET SHOP 3'} ║
╚══════╩═══════════════════════╝

然后我在单个 item-dict 列上应用 json_normalize。

╔══════╦═══════════════════════╦═══════════════════════╗
║ ID   ║ CareCenter            ║ CareCenter_Name       ║
╠══════╬═══════════════════════╬═══════════════════════╣
║ 1    ║ {'Name':'PET SHOP 1'} ║ PET SHOP 1            ║
╠══════╬═══════════════════════╬═══════════════════════╣
║ 10   ║ {'Name':'PET SHOP 2'} ║ PET SHOP 2            ║
╠══════╬═══════════════════════╬═══════════════════════╣
║ 1234 ║ {'Name':'PET SHOP 3'} ║ PET SHOP 3            ║
╚══════╩═══════════════════════╩═══════════════════════╝

然后将其加入到 ID 列上的原始df中。 使用与原始列名称连接的键名称并删除原始列。

╔══════╦══════╦══════════════════════════════════╦═════════════════╗
║ ID   ║ Name ║ Pets                             ║ CareCenter_Name ║
╠══════╬══════╬══════════════════════════════════╬═════════════════╣
║ 1    ║ John ║ [{'Name':'Alvin','Breed':'Dog'}, ║ PET SHOP 1      ║
║      ║      ║ {'Name':'Rex','Type':'Cat'}]     ║                 ║
╠══════╬══════╬══════════════════════════════════╬═════════════════╣
║ 10   ║ Mary ║ {'Name':'Rose','Type':'Cat'}     ║ PET SHOP 2      ║
╠══════╬══════╬══════════════════════════════════╬═════════════════╣
║ 1234 ║ Joe  ║ {'Name':'Max','Type':'Bird'}     ║ PET SHOP 3      ║
╚══════╩══════╩══════════════════════════════════╩═════════════════╝

3.3)如果该列是字典列表,我会像这样创建一个新的df ,只取ID和现任列:

╔══════╦══════════════════════════════════╗
║ ID   ║ Pets                             ║
╠══════╬══════════════════════════════════╣
║ 1    ║ [{'Name':'Alvin','Breed':'Dog'}, ║
║      ║ {'Name':'Rex','Type':'Cat'}]     ║
╠══════╬══════════════════════════════════╣
║ 10   ║ {'Name':'Rose','Type':'Cat'}     ║
╠══════╬══════════════════════════════════╣
║ 1234 ║ {'Name':'Max','Type':'Bird'}     ║
╚══════╩══════════════════════════════════╝

但是,我不知道如何将每个嵌套键的值连接到新列中,我正在寻找类似的东西,之后我可以从那里取出它并将其加入原始df 连接字符串的顺序并不重要,只要它们在正确的列中

╔══════╦═══════════╦═══════════╗
║ ID   ║ Pets_Name ║ Pets_Type ║
╠══════╬═══════════╬═══════════╣
║ 1    ║ Alvin,Rex ║ Dog,Cat   ║
╠══════╬═══════════╬═══════════╣
║ 10   ║ Rose      ║ Cat       ║
╠══════╬═══════════╬═══════════╣
║ 1234 ║ Name      ║ Bird      ║
╚══════╩═══════════╩═══════════╝

到目前为止,这是我的代码:

for column in data_df:
        if data_df.dtypes[column] == "object":
            new = data_df[['Id', column]].copy()
            new = new.dropna(subset = [column])
            a = (new.sample(1).applymap(type) == list).all()
            islist = False
            for i,v in a.items():
                if(v==True and i==column):
                    islist = True
            if(islist==True):
                for c in(json_normalize(new[column].sample(1).iloc[0])):
******STUCK*****    new = new.join(','.join({v for x in new[column] for y in x for k,v in y.items() if k==c}))  ****** STUCK ****
            else:
                new = new.join(json_normalize(new[column]))
            new = new.drop(column,axis=1)
            new = new.add_prefix(column + '_')
            #data_df=data_df.join(new, on='Id',how='left')
            data_df=pd.merge(data_df, new, how='left', left_on='Id', right_on=column + '_Id' )
            data_df = data_df.drop(column, 1)
            data_df = data_df.drop(column + '_Id', 1)

编辑:这将是我正在寻找的决赛桌

╔══════╦══════╦═══════════╦═══════════╦═════════════════╗
║ ID   ║ Name ║ Pets_Name ║ Pets_Type ║ CareCenter_Name ║
╠══════╬══════╬═══════════╬═══════════╬═════════════════╣
║ 1    ║ John ║ Alvin,Rex ║ Dog,Cat   ║ PET SHOP 1      ║
╠══════╬══════╬═══════════╬═══════════╬═════════════════╣
║ 10   ║ Mary ║ Rose      ║ Cat       ║ PET SHOP 2      ║
╠══════╬══════╬═══════════╬═══════════╬═════════════════╣
║ 1234 ║ Joe  ║ Max       ║ Bird      ║ PET SHOP 3      ║
╚══════╩══════╩═══════════╩═══════════╩═════════════════╝

提前感谢您能给我的任何指示,

最终编辑:

这是我在@BEN_YO 的帮助下的工作代码

for column in data_df:
        #mytype = data_df.dtypes[column]
        mn = data_df.sample(1).applymap(type)
        mytype = mn[column].values[0]
        if mytype is dict or mytype is list:
            new = data_df[['Id', column]].copy()
            new = new.dropna(subset = [column])
            a = (new.sample(1).applymap(type) == list).all()
            islist = False
            for i,v in a.items():
                if(v==True and i==column):
                    islist = True
            if(islist==True):
                for c in(json_normalize(new[column].sample(1).iloc[0])):
                    #new = new.join(','.join({v for x in new[column] for y in x for k,v in y.items() if k==c}))
                    new = new.join(new[column].explode().apply(pd.Series).groupby(level=0)[[c]].agg(','.join))
                    #print(column)
            else:
                new = new.join(json_normalize(new[column]))
            new = new.drop(column,axis=1)
            new = new.add_prefix(column + '_')
            #data_df=data_df.join(new, on='Id',how='left')
            data_df=pd.merge(data_df, new, how='left', left_on='Id', right_on=column + '_Id' )
            data_df = data_df.drop(column, 1)
            data_df = data_df.drop(column + '_Id', 1)

尝试explode

out = df.join(df['Pets'].explode().apply(pd.Series).groupby(level=0)[['Name']].agg(','.join))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM