用 Python 定义 Schema 并生成 Parquet 文件

原来用 Java 和 Python 实现过 Avro 转换成 Parquet 格式,所以 Schema 都是在 Avro 中定义的。这里要尝试的是如何定义 Parquet 的 Schema, 然后据此填充数据并生成 Parquet 文件。

本文将演示两个例子,一个是没有层级的两个字段,另一个是含于嵌套级别的字段,将要使用到的 Python 模块有 pandas 和 pyarrow

简单字段定义

定义 Schema 并生成 Parquet 文件

阅读全文 >>

类别: Python. 标签: , . 阅读(4). 评论(0) »

Python 子进程与子进程池的应用

去年记录过一篇如何使用 Python 的线程,线程池的日志 Python 多线程编程, 需用到 threading.Thread, concurrent.futures.ThreadPoolExecutor。本文可以当作是上一文 Python 多线程编程的姊妹篇。

Python 的多线程受到 GIL(Global Interpreter Lock) 的限制,GIL 是一把加到了 Python 的解释器的锁,使得在任意时刻只允许一个 Python  进程使用 Python 解释器,也就是任意时刻,Python 只有一个线程在运行。

GIL 严重影响了计算密集型(CPU-bound) 的多线程程序,此时的多线程与单线程性能没什么差异,也发挥不了多核的威力。但对 I/O 密集型(I/O-bound) 影响不大,因为 CPU 多数时候是在等待。

为了突破 GIL 的 CPU 密集型程序的限制,可以使用非 CPython 解释器,如 Jython, IronPython 或 PyPy, 更为现实的做法就是使用子进程来替代线程去承担较为繁重的计算任务,因为 GIL 是加在进程上的,所以新的进程有独立的 GIL. 阅读全文 >>

类别: Python. 标签: , . 阅读(31). 评论(0) »

Python 调用动态库时 Segmentation fault (core dumped) 问题

这几天一直纠缠在如何调用动态库的问题上,先是 Go 语言,而后迁移到 Python 语言。在测试 Python 调用动态库时,出现过 "Segmentation fault (core dumped)" 的问题,本文记录下怎么去寻找线索,找到并解决问题的。

出现 "Segmentation fault (core dumped)" 的原因是多方面的,比如在 C/C++ 语言中

  1. 内存访问越界(数组越界,strcpy, strcat, sprintf, strcmp 等字符串函数读写越界)
  2. 多线程使用了线程不安全的函数
  3. 多线程读写的数据未加锁保护
  4. 非法指针(NULL 指针,随意的指针类型转换
  5. 堆栈溢出(如大的分配在栈上的局部变量)

用 Python 来调用动态库很大的可能性会是内存访问越界 阅读全文 >>

类别: Python. 标签: . 阅读(42). 评论(0) »

Python 调用 C 动态库(Linux)

Go 调用 C 写的动态库完整例子(Linux版) 弄完了 Go 语言如何调用动态库,又开始琢磨起 Python 怎么调用动态库,首先仍然是以前一篇中的 C 实现为例,C 函数为原型为 char * Add(char* src, int n), 由于用符号直接定位函数,所以无需 C 的头文件。本文仍然是以 Linux 平台为例,GCC 编译为动态库 so 文件。并实验了两个例子,一个为基本的类型,char* 和  int, 再一个就是在 C 中使用到了结构体指针和无类型指针(void*) 时,如何在 Python 进行调用。

测试环境为:

  1. Linux Ubuntu 20.04
  2. gcc: gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
  3. Python: 3.8.10

阅读全文 >>

类别: Python. 标签: , . 阅读(40). 评论(0) »

Python 转换 Apache Avro 数据为 Parquet 格式

前面尝试过用 Java 转换 Apache Avro 数据为 Parquet 格式,本文用 Python 来做同样的事情,并且加入 logicalType: date 类型的支持。本测试中的 Avro 数据也是由 Python 代码生成的。

重复一句 Avro 与 Parquet 的最粗略的区别:Avro 广泛的应用于数据的序列化,如 Kafka,它是基于行的格式,可被流式处理,而 Parquet 是列式存储格式的,适合于基于列的查询。

第一步,生成 Avro 数据文件 user.avro, 须先安装 fastavro

pip install fastavro

生成 user.avro 的代码

阅读全文 >>

类别: Python. 标签: , . 阅读(83). 评论(0) »

从 Notbook 到 JupyterLab, 再配上代码帮手 Kite

又一月有半未落下一个符号了,越来越喜爱用 Python 来高效的辅助日常工作了。先前在 Shell 下使用 Python 代码,因为 Vim 可以配置 Kite 进行代码的自动完成。很早就知道 Jupyter Notebook, 但觉得它还不够漂亮,又没代码提示,也就一直没理会它,后来看到 Kite 可以支持 JupyterLab, 一启动 JupyterLab 的那一瞬间,果然比 Notebook 高大上了许多。有了 Kite  加持,写代码更是顺畅的多,当然还飞不起来。Notebook  应该是一个更经典的工具,它的一系列插件还得稍稍移植到 JupyterLab 上去才能用。

本文快速体验一下 JupyterLab, 从自身到几个基本插件的安装。本人使用的操作系统是 Mac OS X, 刚开始用 python -m venv jupyterlab-venv 创建的虚拟环境中用 pip 来安装,后来发现不知何时在我的 Python 3.8 的 bin 目录中居然安装有 jupyter 和 jupyter-lab 命令,pip install jupyterlabjupyter-lab --version 和 jupyter lab --version 显示的是不同版本 阅读全文 >>

类别: Python. 标签: , . 阅读(1,422). Comments Off on 从 Notbook 到 JupyterLab, 再配上代码帮手 Kite »

Python 处理 JSON 必要时我选择 ujson 和 orjson

在 Python 使用用  json.dumps(data) 时突然发现特别慢,data 本身不大,但是一个包含很多元素的列表,所以促使本人寻找一个替代的 JSON 处理库。大概对比了一个 ujson(UtltraJSON), python-rapidjson(RapidJSON) 和 Python 自带的 json 库。还有一个 simplejson 是为兼容 Python 2.6 以前用的(json 是 Python 2.6 新加入的 API),性能有些差。

基本上姜还是老的辣,想要收获更好的性能,还得仰赖传统的 C/C++ 语言,ujson 是用纯 C 写的,RapidJSON 是 C++ 写的,后者还是十美分的开源产品。json, ujson, rapidjson 三者 loads() 方法的性能差别不太明显,但 dumps() 大对象时 Python 自带的 json 库就要考验用户的耐心了。

注:最开始本来认定了 ujson 为最佳选择, 所以先从 usjon 和 rapidjson 切入的,后来写作本文的过程中,从 usjon 的自我介绍中发现了 Rust 写的 orjson 很显眼,才加入了 orjson 的测试,看来 orjson 更值得拥有。

阅读全文 >>

类别: Python. 标签: , . 阅读(734). 评论(2) »

Python 包管理及虚拟环境的应用(四: conda)

一年半以前写了关于 Python 包管理及虚拟环境系列

  1. Python 包管理及虚拟环境的应用(一: pip)
  2. Python 包管理及虚拟环境的应用(二: virtualenv)
  3. Python 包管理及虚拟环境的应用(三: pipenv)

其中历数了 virtualenv, python3 -m venv, pipenv, 并提到了 pyenv 和 conda。但对 pyenv 和 conda 未作介绍,其中 conda 似乎不该错过。 Anaconda 着力于为数据分析提供支撑,并与 Jupyter Notebook 有更完美的结合,而且 PyCharm 中对它也有很好支持。因此本文来了解一下 conda 以及 Anaconda。

首先 Anaconda 是什么,它是一个用于科学计算的,跨平台的包管理与 Python 环境的工具,它方便的解决了多版本 Python 并存,切换及第三方包安装的问题。所以 Anaconda 不只是像 venv, pipenv 那样的创建管理 Python 虚拟环境,还承担了系统软件的安装管理,像 Mac 下的 brew 那样的功能。一般来说我们没有必要安装 Anaconda, 只需要安装 Miniconda 获得 conda 这个命令行工具即可。 阅读全文 >>

类别: Python. 标签: , . 阅读(358). 评论(0) »

Python 3.7 所带来的新特性

Python 接触的晚,所以接着 体验一下 Python 3.8 带来的主要新特性 继续往前翻,体验一下 Python 3.7 曾经引入的新特性,爱一门语言就要了解她真正的历史。一步一步慢慢给 Python 来个起底。

先来看看 Python 网站的各版本使用情况 Usage statistics of Python Version 3 for websites, 这里统计的 Python 开发的网站的数据,应该有 Python 3 大规模的用于其他领域。单网站应用 Python  来说,Python 2 还有大量遗留代码,Python 3 还是 3.6 为主,Python 的升级还任重道远。本人也是谨慎的在从 3.7 迁移到 3.8 的过程中,AWS 的 Lambda 都支持 3.8,直接上 3.8 也没什么历史负担。以下是从网站使用 Python 统计情况中的两个截图

Python 3.7.0 发布于 2018-06-27, 这篇文章 Cool New Features in Python 3.7 详细介绍了 Python 3.7 的新特性,本文也是从其中挑几个来体验体验。 阅读全文 >>

类别: Python. 标签: . 阅读(115). 评论(0) »

Python 线程池使用有限大小的工作队列

在去年的一篇 Python 多线程编程 中学习了 Python 中如何使用多线程来调度任务,工作中也不时从自己的博客中找来参考。在运用当中不时的碰到内存消耗殆尽情况,直接把命令行窗口打死,不得不强行关窗口或杀进程。之前一直未意识到问题所在,只知任务太多就必死无疑,现在要用 Python 来处理大量任务了,必须着手来解决一下它。其实原因很简单,和 Java 的 ThreadPoolExecutor 一样(看它们用的类名都是一样的)。Java 的  ThreadPoolExecutor 内部使用了一个 Integer.MAX_VALUE 的 LinkedBlockingQueue 来存放提交的待处理的任务,所以基本上就是一个无底洞,自然解决办法也是类似的,需要一个 Bounded Queue 来存放任务列表。

在解决该问题之前自己也不妨来温习一下 Python 中使用线程池的基本模式,下面的模板代码曾经是我的最爱:

在上面的 with 上下文中会进行以下几步 阅读全文 >>

类别: Python. 标签: . 阅读(631). 评论(1) »