看来斯帕克对这里的这些行做了些疯狂的事。使用RDDs,我可以获得更好的性能(每个CPU内核每秒1/3行,而数据帧的每个CPU核心每秒1/40行)。但这仍然不是很快。在df = sql_context.read.orc('/path/to/source/file')
rdd = df.rdd
def expand(row):
contig, start, ref, alt, gt = row
def getrow(index, genotype):
return contig, start, ref, alt, index, genotype
return [getrow(index, genotype) for index, genotype in enumerate(gt)]
rdd_flat = rdd.flatMap(expand)
schema = ('contig', 'start', 'ref', 'alt', 'index', 'genotype')
sqlc.createDataFrame(rdd_flat, schema=schema).write.orc('/path/to/output/file')
有趣的是如果我把扩展函数重新定义为
^{pr2}$
它的运行速度大约慢13倍(一个函数调用大约需要1.4秒)。在
很明显,row对象的效率非常低。在
不过,还有更多的问题需要解决。单个核心应该能够每秒运行扩展函数9次,但实际性能是每3秒运行1行。在
编辑:找到一个“解决方案”:使用prestodb查询而不是spark。它以每秒超过1行的速度运行,比数据帧快20倍,比RDD快4倍:create table flat (
contig varchar,
start int,
ref varchar,
alt varchar,
index bigint,
genotype tinyint
)
WITH (format = 'ORC');
insert into flat
select contig, start, ref, alt, index, genotype, partition_name
from nested cross join unnest(gt) with ordinality as g (genotype, index)
where partition_name='10-70329347';