如何从 Python Pandas Dataframe 中的 STRING 列中提取嵌套字典?

Posted

技术标签:

【中文标题】如何从 Python Pandas Dataframe 中的 STRING 列中提取嵌套字典?【英文标题】:How to extract a nested dictionary from a STRING column in Python Pandas Dataframe? 【发布时间】:2021-03-01 07:31:15 【问题描述】:

有一张表,其列event 的一个数据点如下所示:

'事件是一个字符串列!

df['event']
RETURNS:
"'eventData': 'type': 'page', 'name': "WHAT'S UP", 'eventId': '1003', 'deviceType': 'kk', 'pageUrl': '/chick 2/whats sup', 'version': '1.0.0.888-10_7_2020__4_18_30', 'sessionGUID': '1b312346a-cd26-4ce6-888-f25143030e02', 'locationid': 'locakdi-3b0c-49e3-ab64-741f07fd4cb3', 'eventDescription': 'Page Load'"

我正在尝试从字典中提取嵌套字典 eventData 并创建一个新列,如下所示:

df['event'] 
RETURNS: 
'eventId': '1003', 'deviceType': 'kk', 'pageUrl': '/chick 2/whats sup', 'version': '1.0.0.888-10_7_2020__4_18_30', 'sessionGUID': '1b312346a-cd26-4ce6-888-f25143030e02', 'locationid': 'locakdi-3b0c-49e3-ab64-741f07fd4cb3', 'eventDescription': 'Page Load'

df['eventData']
RETURNS:
'type': 'page', 'name': "WHAT'S UP"

我该怎么做?

【问题讨论】:

【参考方案1】:

我会考虑在event 列上使用pandas apply 方法。

如果 eventData 键预计会出现在数据框所有行的 event 列字典中,则以下内容可能就足够了

import json
import numpy as np

def get_event_data_from_event(event_str):
    """
    Convert event string to dict and return event_data
    """
    try:
        event_as_dict = json.loads(event_str)
    except json.decoder.JSONDecodeError:
        return np.nan
    else
        if not "eventData" in event_as_dict.keys():
            return np.nan
        return event_as_dict["eventData"]  

df["eventData"] = df["event"].apply(lambda x: get_event_data_from_event(x))

如果event 字典的格式不符合您的预期,则eventData 列中的该行将返回N/A。

然后您可以使用 dropna 删除那些不符合要求的行,如下所示:

df_subset = df.dropna(axis='columns', subset="eventData")

【讨论】:

抱歉误导。 'event' 列实际上是一个 STRING 列。我能想到的唯一方法是应用 REGEX 从该字符串中获取第二个大括号“ ”并创建一个新列。您知道如何为这种情况构建正则表达式吗? 我已经更新了上面的答案,期望事件列是一个字符串。您可以使用json.loads 将 json 字符串加载为 dict/list 对象。【参考方案2】:

我终于从另一个帖子中找到了答案: Python flatten multilevel/nested JSON

使用方法: json_col = pd.DataFrame([flatten_json(x) for x in df['json_column']])

def flatten_json(nested_json, exclude=['']):
    out = 
    def flatten(x, name='', exclude=exclude):
        if type(x) is dict:
            for a in x:
                if a not in exclude: flatten(x[a], name + a + '_')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + '_')
                i += 1
        else:
            out[name[:-1]] = x

    flatten(nested_json)
    return out 

【讨论】:

以上是关于如何从 Python Pandas Dataframe 中的 STRING 列中提取嵌套字典?的主要内容,如果未能解决你的问题,请参考以下文章

肝了3天,整理了90个Pandas案例!

Python Pandas Dataframe:规范化 0.01 到 0.99 之间的数据?

如何用pandas将某列one-hot编码后,修改原dataframe

如果数据类型错误,如何跳过加载到 Pandas 数据框的 excel 文件的行(检查类型)

Pandas库的学习

Python/Pandas:如何从 datetime64[ns] 转换为 datetime