pandas - 来自 pandas 的 Arrow ListArray 与笨拙生成的箭头数组的结构有很大不同?
问题描述
我遇到了以下问题,进行了一些测试,以证明 pyspark 中的纯 pyarrow UDF 与始终通过 pandas 相比的有用性。
import awkward
import numpy
import pandas
import pyarrow
counts = numpy.random.randint(0,20,size=200000)
content = numpy.random.normal(size=counts.sum())
test_jagged = awkward.JaggedArray.fromcounts(counts, content)
test_arrow = awkward.toarrow(test_jagged)
def awk_arrow(col):
jagged = awkward.fromarrow(col)
jagged2 = jagged**2
return awkward.toarrow(jagged2)
def pds_arrow(col):
pds = col.to_pandas()
pds2 = pds**2
return pyarrow.Array.from_pandas(pds2)
out1 = awk_arrow(test_arrow)
out2 = pds_arrow(test_arrow)
out3 = awkward.fromarrow(out1)
out4 = awkward.fromarrow(out2)
type(out3)
type(out4)
产量
<class 'awkward.array.jagged.JaggedArray'>
<class 'awkward.array.masked.BitMaskedArray'>
和
out3 == out4
产生(在堆栈跟踪的末尾):
AttributeError: no column named 'reshape'
查看数组:
print(out3);print();print(out4);
[[0.00736072240594475 0.055560612050914775 0.4094101942882973 ... 2.4428454924678533 0.07220045904440388 3.627270394986972] [0.16496227597707766 0.44899025266849046 1.314602433843517 ... 0.07384558862546337 0.5655043672418324 4.647396184088295] [0.04356259421421215 1.8983172440218923 0.10442121937532822 0.7222467989756899 0.03199694383894229 0.954281670741488] ... [0.23437909336737087 2.3050822727237272 0.10325064534860394 0.685018355096147] [0.8678765133108529 0.007214659054089928 0.3674379091794599 0.1891573101427716 2.1412651888713317 0.1461282900111415] [0.3315468986268042 2.7520115602119772 1.3905787720409803 ... 4.476255451581318 0.7237199572195625 0.8820112289563018]]
[[0.00736072240594475 0.055560612050914775 0.4094101942882973 ... 2.4428454924678533 0.07220045904440388 3.627270394986972] [0.16496227597707766 0.44899025266849046 1.314602433843517 ... 0.07384558862546337 0.5655043672418324 4.647396184088295] [0.04356259421421215 1.8983172440218923 0.10442121937532822 0.7222467989756899 0.03199694383894229 0.954281670741488] ... [0.23437909336737087 2.3050822727237272 0.10325064534860394 0.685018355096147] [0.8678765133108529 0.007214659054089928 0.3674379091794599 0.1891573101427716 2.1412651888713317 0.1461282900111415] [0.3315468986268042 2.7520115602119772 1.3905787720409803 ... 4.476255451581318 0.7237199572195625 0.8820112289563018]]
可以看到数组的内容和形状都是一样的,但是表面上没有可比性,非常反直觉。是否有充分的理由将没有 Null 的密集锯齿状结构表示为 BitMaskedArray?
解决方案
Arrow 中的所有数据都可以为空(在每个级别),并且它们使用位掩码(与字节掩码相反)来指定哪些元素是有效的。该规范允许完全有效数据的列不写入位掩码,但并非每个写入者都利用这种自由。很多时候,您会看到不必要的位掩码。
当它遇到一个位掩码时,例如 here,笨拙地插入一个BitMaskedArray
.
可以更改它以检查掩码是否不必要并跳过该步骤,尽管这会增加一个随数据集大小缩放的操作(尽管在大多数情况下可能无关紧要——位掩码的检查速度是字节掩码的 8 倍)。这也有点复杂:如果数据集的长度不是 8 的倍数,则最后一个字节可能不完整。需要单独检查这些位,但可以批量检查掩码的其余部分。(甚至可能int64
一次检查 64 个标志。)
推荐阅读
- image - Vaadin 拒绝在 HorizontalLayout 中对齐图像
- c - 为什么我不能使用带有字符指针变量的 scanf() 或 gets() strcat() strcpy() 等字符串函数?
- node.js - Heroku Node.js 应用程序不断崩溃并重新启动
- python - python:模拟类变量的多重继承
- reactjs - 在ajax调用后反应更新dom模板
- javascript - 基于用户输入的 JavaScript 字体颜色变化
- python - Pandas:如果无序,则跨列对 DataFrame 单元格进行排序
- java - JDK11 HttpClient 双向 tls
- php - Laravel 5.8 Class XXX 注入时不存在
- javascript - TypeORM 中的 OneToMany 关系在哪里