在 Pandas 数据框中使用 JSON 数据规范化列

Posted

技术标签:

【中文标题】在 Pandas 数据框中使用 JSON 数据规范化列【英文标题】:Normalize column with JSON data in Pandas dataframe 【发布时间】:2020-12-15 14:59:14 【问题描述】:

我有一个 Pandas 数据框,其中一列包含 JSON 数据(JSON 结构很简单:只有一层,没有嵌套数据):

ID,Date,attributes
9001,2020-07-01T00:00:06Z,""State":"FL","Source":"android","Request":"0.001""
9002,2020-07-01T00:00:33Z,""State":"NY","Source":"Android","Request":"0.001""
9003,2020-07-01T00:07:19Z,""State":"FL","Source":"ios","Request":"0.001""
9004,2020-07-01T00:11:30Z,""State":"NY","Source":"windows","Request":"0.001""
9005,2020-07-01T00:15:23Z,""State":"FL","Source":"ios","Request":"0.001""

我想规范化 attributes 列中的 JSON 内容,以便 JSON 属性成为数据框中的每个列。

ID,Date,attributes.State, attributes.Source, attributes.Request
9001,2020-07-01T00:00:06Z,FL,Android,0.001
9002,2020-07-01T00:00:33Z,NY,Android,0.001
9003,2020-07-01T00:07:19Z,FL,ios,0.001
9004,2020-07-01T00:11:30Z,NY,windows,0.001
9005,2020-07-01T00:15:23Z,FL,ios,0.001 

我一直在尝试使用需要字典的Pandas json_normalize。所以,我想我会将 attributes 列转换为字典,但它并没有达到预期的效果,因为字典的格式如下:

df.attributes.to_dict()

0: '"State":"FL","Source":"Android","Request":"0.001"',
 1: '"State":"NY","Source":"Android","Request":"0.001"',
 2: '"State":"FL","Source":"ios","Request":"0.001"',
 3: '"State":"NY","Source":"windows","Request":"0.001"',
 4: '"State":"FL","Source":"ios","Request":"0.001"'

并且规范化采用键 (0, 1, 2, ...) 作为列名,而不是 JSON 键。

我感觉我已经很接近了,但我不知道如何准确地做到这一点。欢迎任何想法。

谢谢!

【问题讨论】:

【参考方案1】:

Normalize 期望作用于对象,而不是字符串。

import json
import pandas as pd
df_final = pd.json_normalize(df.attributes.apply(json.loads))

【讨论】:

这对我有用。我有一个使用 read_csv 方法读取的 .tsv 文件。然后当我将 df 传递给 json_normalize 时,它只是在输出索引。我的专栏只是一个字符串。我转换为一个对象,瞧!谢谢【参考方案2】:

我找到了一个解决方案,但我对它并不太满意。我认为这是非常低效的。

import pandas as pd
import json

# Import full dataframe
df = pd.read_csv(r'D:/tmp/sample_simple.csv', parse_dates=['Date'])

# Create empty dataframe to hold the results of data conversion
df_attributes = pd.DataFrame()

# Loop through the data to fill the dataframe
for index in df.index:
    row_json = json.loads(df.attributes[index])
    normalized_row = pd.json_normalize(row_json)
    df_attributes = df_attributes.append(normalized_row)

# Reset the index of the attributes dataframe
df_attributes = df_attributes.reset_index(drop=True)

# Drop the original attributes column
df = df.drop(columns=['attributes'])

# Join the results
df_final = df.join(df_attributes)

# Show results
print(df_final)
print(df_final.info())

这给了我预期的结果。但是,正如我所说,它有几个效率低下的地方。对于初学者,数据框附加在 for 循环 中。根据文档,最佳做法是制作一个列表然后追加,但我无法弄清楚如何在保持我想要的形状的同时做到这一点。我欢迎所有的批评和想法。

【讨论】:

【参考方案3】:

您不需要先转换为字典。

试试:

import pandas as pd

pd.json_normalize(df[‘attributes’])

【讨论】:

嗨@欧文。我已经尝试过,但出现错误: AttributeError: 'str' object has no attribute 'values 如果我尝试 pd.json_normalize(df['attributes'].values) 数据是如何导入的? 嗨@Owen,这只是一个简单的import pandas as pddf = pd.read_csv('datafile.csv') 不确定这是否有帮助,似乎是类似的情况。如果没有道歉:***.com/questions/49671693/… 谢谢@Owen。这是一个有趣的话题。它不符合我的需要。我拥有的数据不是一组字典,并且得到它使我处于与原始问题非常相似的位置。但我很欣赏这种努力。谢谢!

以上是关于在 Pandas 数据框中使用 JSON 数据规范化列的主要内容,如果未能解决你的问题,请参考以下文章

Pandas - 规范化 Json 列表

如何从 pandas 数据框中的大型每日 JSON 数据集计算平均月值?

如何将 json 加载到 pandas 数据框中?

无法在 python pandas 数据框中附加嵌套的 JSON 值

Pandas 如何从 JSON 索引列表并将其放入数据框中?

Pandas - 在数据框中的列内扩展嵌套的 json 数组