提取作为字符串嵌入 Pandas 数据帧中的嵌套 JSON

2024-01-04

我有一个 CSV,其中一个字段是嵌套的 JSON 对象,存储为字符串。我想将 CSV 加载到数据框中,并将 JSON 解析为附加到原始数据框的一组字段;换句话说,提取 JSON 的内容并使它们成为数据帧的一部分。

My CSV:

id|dist|json_request
1|67|{"loc":{"lat":45.7, "lon":38.9},"arrival": "Monday", "characteristics":{"body":{"color":"red", "make":"sedan"}, "manuf_year":2014}}
2|34|{"loc":{"lat":46.89, "lon":36.7},"arrival": "Tuesday", "characteristics":{"body":{"color":"blue", "make":"sedan"}, "manuf_year":2014}}
3|98|{"loc":{"lat":45.70, "lon":31.0}, "characteristics":{"body":{"color":"yellow"}, "manuf_year":2010}}

请注意,并非所有行的所有键都相同。 我希望它生成一个与此等效的数据框:

data = {'id'     : [1, 2, 3],
        'dist'  : [67, 34, 98],
        'loc_lat': [45.7, 46.89, 45.70],
        'loc_lon': [38.9, 36.7, 31.0],
        'arrival': ["Monday", "Tuesday", "NA"],
        'characteristics_body_color':["red", "blue", "yellow"],
        'characteristics_body_make':["sedan", "sedan", "NA"],
        'characteristics_manuf_year':[2014, 2014, 2010]}
df = pd.DataFrame(data)

(我真的很抱歉,我无法让表格本身看起来很合理!请不要生我的气,我是一个菜鸟:()

我尝试过的

经过一番折腾后,我想出了以下解决方案:

#Import data
df_raw = pd.read_csv("sample.csv", delimiter="|")

#Parsing function
def parse_request(s):
    sj = json.loads(s)
    norm = json_normalize(sj)
    return norm

#Create an empty dataframe to store results
parsed = pd.DataFrame(columns=['id'])

#Loop through and parse JSON in each row
for i in df_raw.json_request:
    parsed = parsed.append(parse_request(i))

#Merge results back onto original dataframe
df_parsed = df_raw.join(parsed)

这显然不优雅而且效率很低(我必须解析 300K 行需要几个小时)。有没有更好的办法?

我看过的地方

我已经解决了以下相关问题:将 CSV 读入 pandas,其中一列是 json 字符串 https://stackoverflow.com/questions/20680272/reading-a-csv-into-pandas-where-one-column-is-a-json-string(这似乎只适用于简单的非嵌套 JSON)

JSON 到 pandas DataFrame https://stackoverflow.com/questions/21104592/json-to-pandas-dataframe(我从中借用了部分解决方案,但我无法弄清楚如何在数据帧中应用此解决方案而不循环遍历行)

我正在使用 Python 3.3 和 Pandas 0.17。


这是一种可以将速度提高 10 到 100 倍的方法,并且可以让您在一分钟内读取大文件,而不是一个多小时。这个想法是只有在读取完所有数据后才构造一个数据帧,从而减少需要分配内存的次数,并且只调用json_normalize对整个数据块而不是每行执行一次:

import csv
import json

import pandas as pd
from pandas.io.json import json_normalize

with open('sample.csv') as fh:
    rows = csv.reader(fh, delimiter='|')
    header = next(rows)

    # "transpose" the data. `data` is now a tuple of strings
    # containing JSON, one for each row
    idents, dists, data = zip(*rows)

data = [json.loads(row) for row in data]
df = json_normalize(data)
df['ids'] = idents
df['dists'] = dists

So that:

>>> print(df)

   arrival characteristics.body.color characteristics.body.make  \
0   Monday                        red                     sedan   
1  Tuesday                       blue                     sedan   
2      NaN                     yellow                       NaN   

   characteristics.manuf_year  loc.lat  loc.lon ids  
0                        2014    45.70     38.9   1  
1                        2014    46.89     36.7   2  
2                        2010    45.70     31.0   3

此外,我还研究了哪些pandas's json_normalize正在执行,并且它正在执行一些深度复制,如果您只是从 CSV 创建数据帧,则不需要这些深度复制。我们可以自己实现flatten函数接受字典并“展平”键,类似于json_normalize做。然后我们可以制作一个生成器,它一次输出数据帧的一行作为记录。这种方法甚至更快:

def flatten(dct, separator='_'):
    """A fast way to flatten a dictionary,"""
    res = {}
    queue = [('', dct)]

    while queue:
        prefix, d = queue.pop()
        for k, v in d.items():
            key = prefix + k
            if not isinstance(v, dict):
                res[key] = v
            else:
                queue.append((key + separator, v))

    return res

def records_from_json(fh):
    """Yields the records from a file object."""
    rows = csv.reader(fh, delimiter='|')
    header = next(rows)
    for ident, dist, data in rows:
        rec = flatten(json.loads(data))
        rec['id'] = ident
        rec['dist'] = dist
        yield rec

def from_records(path):
    with open(path) as fh:
        return pd.DataFrame.from_records(records_from_json(fh))

这是计时实验的结果,我通过重复行人为地增加了样本数据的大小。行数表示为n_rows:

        method 1 (s)  method 2 (s)  original time (s)
n_rows                                               
96          0.008217      0.002971           0.362257
192         0.014484      0.004720           0.678590
384         0.027308      0.008720           1.373918
768         0.055644      0.016175           2.791400
1536        0.105730      0.030914           5.727828
3072        0.209049      0.060105          11.877403

线性推断,第一种方法应该在大约 20 秒内读取 300k 行,而第二种方法应该需要大约 6 秒。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

提取作为字符串嵌入 Pandas 数据帧中的嵌套 JSON 的相关文章

  • 按日期对 JSON 进行排序

    我知道这一定相对简单 但我有一个 JSON 数据集 我想按日期排序 到目前为止 我每次都会遇到问题 现在我将日期存储为this lastUpdated 如果有帮助的话 我可以访问 jquery 但我意识到 sort 是本机 JS 提前致谢
  • 如何在 pygame 中聚焦光线或如何仅绘制窗口的某些圆形部分?

    对于这一点 如果您熟悉它 请想想 超级马里奥制造2 中嘘关卡中的黑暗模式 我试图在角色周围创建一个圆形聚光灯 这也将使圆圈范围内的任何内容都可见 例如部分站在地板上 敌人或场景中的任何其他物体 我的计划是首先绘制圆圈 聚光灯 然后绘制场景
  • 读取r中不同目录中的多个文件[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想从不同的目录读取多个 csv 文件 然后将其放入单个数据框中 我有两种目录可供阅读 A LogIIS 文件夹01 文件 csv 在
  • 为什么我无法解开根节点并反序列化对象数组?

    为什么我无法通过展开根节点来反序列化对象数组 import java io IOException import java util Arrays import java util List import org codehaus jack
  • WTForms 中的小数字段舍入

    我有一个包含价格小数字段的表单 如下所示 from flask ext wtf import Form import wtforms from wtforms validators import DataRequired from deci
  • 肥皂服务的良好框架是什么?

    我正在寻找一个用于肥皂的好框架service 我更喜欢使用Pythonic框架 但是在查看了soaplib rpclib 太不稳定 SOAPy 不适用于2 7 和ZSI 太 令人困惑 之后 我不确定这是否可能 我对使用另一种语言感到满意 尽
  • Python MySQL 模块

    我正在开发一个需要与 MySQL 数据库交互的 Web 应用程序 但我似乎找不到任何真正适合 Python 的模块 我特别寻找快速模块 能够处理数十万个连接 和查询 所有这些都在短时间内完成 而不会对速度产生重大影响 我想我的答案将是游戏领
  • 更改Python pylab玫瑰/极坐标图中图例标题的字体大小

    我正在尝试更改玫瑰图或 极地 图上现有图例标题的字体大小 大部分代码是由不在的其他人编写的 我已经添加 ax legend title legend title setp l get title fontsize 8 添加标题 legend
  • ValueError:在 R 中使用 keras 模型时在用户代码中

    我正在尝试使用 R 在 R 中运行一维 CNNkeras包裹 我正在使用以下代码 library MASS library keras Create some data data Boston data lt Boston create a
  • 如何使用泛型类型的构造函数

    如何使用 python 泛型类型的构造函数 T typing TypeVar T class MyClass typing Generic T def init self initialValue typing Iterable self
  • 将 csv 文件按多列拆分为 panda 数据框

    我有一个包含多列的 tsv 文件 有 10 多列 但对我来说重要的列是名称为 user name shift id url id 的列 我想创建一个数据框 首先根据用户名分隔整个 csv 文件 即只有具有相同用户名的行才会分组在一起 从该块
  • Cython:为什么 size_t 比 int 快?

    更改某些 Cython 变量的类型int输入size t可以显着减少某些功能的时间 30 但我不明白为什么 例如 cimport numpy as cnp import numpy as np def sum int cnp int64 t
  • 不重复的Python组合

    我有一个数字列表 我想从中进行组合 如果我有清单 t 2 2 2 2 4 c list itertools combinations t 4 结果是 2 2 2 2 2 2 2 4 2 2 2 4 2 2 2 4 2 2 2 4 但我想得到
  • 对于 pygtk 应用程序来说,什么是好的嵌入式浏览器?

    我计划在我的 pygtk 应用程序中使用嵌入式浏览器 并且我正在 gtkmozembed 和 pywebkitgtk 之间进行辩论 两者之间有什么引人注目的区别吗 还有我不知道的第三种选择吗 应该注意的是 我不会使用它来访问网络上的内容 我
  • 如何在树莓派上更新到最新的 python 3.5.1 版本?

    我昨天拿到了 Raspberry Pi 我已经在尝试用它来编写代码了 我有一个计划在其上运行的程序 但它仅与 Python 版本 3 5 0 或 3 5 1 兼容 并且我在互联网上找到的所有内容似乎都已经过时 与 Python 2 有关 或
  • python 函数返回 javascript date.getTime()

    我正在尝试创建一个简单的 python 函数 它将返回与 javascript 相同的值new Date getTime 方法 如所写here http www w3schools com js js dates asp javascrip
  • Networkx 中 Louvain 分区的可视化

    请帮助我更改 Louvain 聚类算法结果的可视化 我从网站上获取了代码https github com taynaud python louvain https github com taynaud python louvain我可以重写
  • 用于桌面数据库应用程序的 Python 框架

    是否有一个框架可以为Python开发桌面数据库应用程序 一些带有CRUD屏幕的屏幕 我正在寻找类似于 Windows 窗体的东西 能够将 TextField Combos 和其他 UI 隐喻与datasets连接到关系数据库例如 MySQL
  • Pandas 替换特定列上的值

    我知道这两个类似的问题 熊猫替换值 https stackoverflow com questions 27117773 pandas replace values Pandas 替换数据框中的列值 https stackoverflow
  • PyQt QFileDialog exec_ 很慢

    我正在使用自定义QFileDialog因为我想选择多个目录 但是exec 功能非常慢 我不明白为什么 我正在使用最新版本的 PyQt 代码片段 from PyQt4 import QtGui QtCore QtNetwork uic cla

随机推荐

  • 每个连接有多个事务的 MySQLdb

    是否可以对多个事务使用单个 MySQLdb 连接而不关闭它们之间的连接 换句话说 是这样的 conn MySQLdb connect host 1 2 3 4 port 1234 user root passwd x db test for
  • 对调用静态方法的类进行单元测试

    我正在尝试对调用类 B 的静态方法的类 A 进行单元测试 类 B 本质上有一个谷歌番石榴缓存 它从给定键的缓存中检索值 对象 或使用服务适配器将对象加载到缓存中 在缓存未命中的情况下 服务适配器类又具有其他自动装配的依赖项来检索对象 这些类
  • jQuery AJAX 跨域

    这里有两个页面 test php 和 testserver php test php
  • 使用opencv捕获单张图片

    我已经看到了有关使用 python 和 opencv 从网络摄像头流中捕获帧的一些内容 但是如何使用 python 和 opencv 以指定分辨率仅捕获一张图片 您可以使用以下命令捕获单个帧VideoCaptureOpenCV的方法 imp
  • 如何在 Github 中显示 D3.js HTML 图表

    我试图让d3 js图可以在github上显示 但是失败了 有没有办法解决这个问题 我已将 d3 html 图推送到 github 中 因为它没有渲染 所以我看不到绘图 你可以尝试使用GitHub 页面 https pages github
  • MySQl,连接/合并2个没有共享列的表并按公共列排序

    我有两个具有相同结构的表 处理不同的数据 我想合并它们 添加一个文本字段 指示该行的数据来自何处 并按公共字段排序 TABLE1 ID NAME YEAR 1 peter 2008 2 edward 2010 TABLE2 ID NAME
  • 山魈回复

    今天我注册了 Mandrill 帐户来了解它是如何工作的 这是我的 PHP 代码 https gist github com anonymous 5ca4c6fe388c465d8076发送一封简单的电子邮件
  • F# FSI,更改工作目录

    我在桌面的 新文件夹 中有以下文件 File location C Users my user name Desktop New folder AddOne fs module internal AddOneModule let AddOn
  • 按周/月/等分组 & ActiveRecord?

    我正在我的产品中进行一些静态计算 用户执行了许多操作 比如说发布了评论 我希望能够向他们展示过去一个月或过去一年每月发布的评论数量 activerecord 有没有办法以这种方式分组 我最好只是手动执行此操作 根据我自己的标准迭代记录求和吗
  • 在不同项目中用作编译的 jar 时,Spring AOP 不起作用

    我有一个工作AOP 当在项目内部使用时它被写入 但是当我构建这个项目 maven安装 并在另一个项目中使用该JAR时 并尝试使用 TimedLog注释 什么也没有发生 我尝试在其中断点 但它没有到达那里 它看起来像这样 Retention
  • 将多个 .exe 打包在单个 .msi 包中

    我试图将多个 exe 放入单个 msi 包中 并且应该一一安装 假设我有 a exe b exe 和 c exe 单击 msi 包时 应安装 a exe 并且 msi 应在成功安装 a exe 后等待它 它应触发 b exe 成功安装 b
  • Shinydashboardplus:如何添加没有标题的框?

    最近更新后ShinydasboardPlus 到2 0 我无法做到box没有标题 也没有标题空间 I tried title NULL headerBorder FALSE and still have this space How to
  • Neo4j 快速匹配模糊文本属性的方法

    我有合理数量的节点 大约 60 000 个 Document title A title 给定一个标题 我想找到匹配的节点 如果存在 问题是我给的标题不一致 也就是说 有时新单词的开头是大写 有时则是全部小写 有时关键字与 Kebab 大小
  • 我是否需要为线程之间的更改通知标志设置内存屏障?

    我需要一个非常快速的 在 读取器成本低 的意义上 而不是 低延迟 线程之间的更改通知机制 以便更新读取缓存 情况 Thread W 编写器 更新数据结构 S 在我的例子中是地图中的设置 只是偶尔一次 Thread R Reader 维护一个
  • devtools::check() 在 devtools::test() 通过的地方失败,因为并非 test 中的所有测试文件都复制到 [r] 上

    我的第一篇 r 帖子 我接手了一个由软件公司开发的项目 该项目由 4 个 R 包组成 在运行测试时 我发现虽然 devtools test 为其中一个包生成了干净的运行 但 devtools check 却没有 输出中的错误如下 gt te
  • 布局管理器boundingRectForGlyphRange:inTextContainer:不适用于所有字符串

    我有一个 UILabel 其中包含类似推文的字符串 其中包括其他用户的提及 Hey stephen and frank and Jason1 我试图让每个提及都是可点击的 这样我就可以加载该用户的个人资料 我从另一个 SO 帖子中找到了一些
  • PYTHONPATH 如何填充 sys.path 是否可靠并有记录?

    在我的机器上 这些值来自PYTHONPATH似乎被插入sys path 从索引 1 开始 订单保留 去重 例如 与PYTHONPATH spam eggs spam然后办理登机手续python m site 我得到如下结果 sys path
  • 如何删除 React Native 中的警告

    我正在开发一个应用程序并且正在使用bottomTabNavigator但与此同时我收到了这个警告 Look like you re passing an inline function for Component prop for the
  • cbegin/cend 背后的原因是什么?

    我想知道为什么cbegin and cendC 11 中引入了 在什么情况下调用这些方法会与 const 重载产生差异begin and end 这很简单 假设我有一个向量 std vector
  • 提取作为字符串嵌入 Pandas 数据帧中的嵌套 JSON

    我有一个 CSV 其中一个字段是嵌套的 JSON 对象 存储为字符串 我想将 CSV 加载到数据框中 并将 JSON 解析为附加到原始数据框的一组字段 换句话说 提取 JSON 的内容并使它们成为数据帧的一部分 My CSV id dist