将标准python键值字典列表转换为pyspark数据帧

时间:2016-06-02 06:17:51

标签: python dictionary apache-spark pyspark

考虑我有一个python字典键值对的列表,其中key对应于表的列名,所以对于下面的列表如何将它转换为带有两个cols arg1 arg2的pyspark数据帧?

 [{"arg1": "", "arg2": ""},{"arg1": "", "arg2": ""},{"arg1": "", "arg2": ""}]

我如何使用以下构造来完成它?

df = sc.parallelize([
    ...
]).toDF

将arg1 arg2放在上面的代码(...)中的位置

5 个答案:

答案 0 :(得分:24)

旧方式:

sc.parallelize([{"arg1": "", "arg2": ""},{"arg1": "", "arg2": ""},{"arg1": "", "arg2": ""}]).toDF()

新方式:

from pyspark.sql import Row
from collections import OrderedDict

def convert_to_row(d: dict) -> Row:
    return Row(**OrderedDict(sorted(d.items())))

sc.parallelize([{"arg1": "", "arg2": ""},{"arg1": "", "arg2": ""},{"arg1": "", "arg2": ""}]) \
    .map(convert_to_row) \ 
    .toDF()

答案 1 :(得分:1)

我必须修改接受的答案,以便在运行Spark 2.0的Python 2.7中为我工作。

library(ggplot2)
df <- data.frame(dens = rnorm(5000),
             split = factor(sample(1:2, 5000, replace = T)),
             method = factor(sample(c("A","B"), 5000, replace = T)),
             counts = factor(sample(c(1, 10, 100, 1000, 10000), 5000, replace = T)))

df$key <- factor(paste(df$split, df$method))

levels(df$split) <- factor(0:2)
library(ggplot2)

ggplot(df, aes(x = interaction(split, counts), y = dens, fill = key)) +
  geom_split_violin(draw_quantiles = c(0.25, 0.5, 0.75)) +
  scale_fill_manual(values=RColorBrewer::brewer.pal(name="Paired",n=4)) + 
  theme_light() + 
  theme(legend.position="bottom") + 
  scale_x_discrete(
    limits = levels(interaction(df$split,df$counts))[-length(levels(interaction(df$split,df$counts)))],
    drop = FALSE, 
    name = "Counts"
  )

答案 2 :(得分:0)

对于任何寻求不同解决方案的人,我发现这对我来说很有效: 我有一本包含键值对的字典-我想将其转换为两个PySpark数据框列:

所以

{k1:v1, k2:v2 ...}

成为

 ---------------- 
| col1   |  col2 |
|----------------|
| k1     |  v1   |
| k2     |  v2   |
 ----------------

lol= list(map(list, mydict.items()))
df = spark.createDataFrame(lol, ["col1", "col2"])

答案 3 :(得分:0)

假设您的数据是结构而不是字符串字典,那么您可以做

newdf = df.select(['df.arg1','df.arg2'])

答案 4 :(得分:0)

其他答案有效,但这里还有一个适用于嵌套数据的单行。这可能不是最有效的,但如果你从内存字典中创建一个 DataFrame,你要么使用像测试数据这样的小数据集,要么错误地使用 spark,所以效率真的不应该是一个问题:

d = {any json compatible dict}
spark.read.json(sc.parallelize([json.dumps(d)]))