【问题标题】:Split a sentence and group each value by key拆分一个句子并按键分组每个值
【发布时间】:2019-09-22 21:51:00
【问题描述】:

我有一个以下格式的输入数据,我正在尝试拆分并创建一个键值对:

输入:

"SQL",1,2,3,4,5
"ORACLE",2,5,6,7

要写入 RDD 的预期数据:

SQL,1
SQL,2
SQL,3
SQL,4
SQL,5
ORACLE,2
ORACLE,5
ORACLE,6
ORACLE,7

我正在尝试使用以下不起作用的代码创建键值对

data_rdd = f.zipWithIndex() \
        .map(lambda row: (row[0].replace('"', '').split(',')[0], (dst for dst in row[1:len(row[0])]))) \
        .aggregateByKey([], lambda a, b: a + [b], lambda a, b: a + b)

【问题讨论】:

  • 对于每一行s,您可以申请:[(s.split(',')[0].replace('"', ''), i) for i in s.split(',')[1:]] 并获取对元组列表。
  • 我之前确实尝试过,如果我使用命令,我会得到一个未定义的行:data_rdd = f.zipWithIndex() \ .map(lambda row: (row[0].split(' ,')[0].replace('"', ''), i) for i in row.split(',')[1:]) \ .aggregateByKey([], lambda a, b: a + [ b], λ a, b: a + b)

标签: python python-3.x lambda pyspark rdd


【解决方案1】:

输入数据:

inp = '''"SQL",1,2,3,4,5
"ORACLE",2,5,6,7'''

代码:

res = []

for line in inp.splitlines():
    values = line.split(',')
    key = values[0].replace('"', '')
    res.extend((key, v) for v in values[1:])

print(res)

注意:它会创建一个 values 的副本,而没有第一个元素来跳过它。

您还可以通过按索引访问values 元素来跳过第一个元素:

res = []

for line in inp.splitlines():
    values = line.split(',')
    key = values[0].replace('"', '')
    res.extend((key, values[i]) for i in range(1, len(values)))

print(res)

输出:

[('SQL', '1'), ('SQL', '2'), ('SQL', '3'), ('SQL', '4'), ('SQL', '5'), ('ORACLE', '2'), ('ORACLE', '5'), ('ORACLE', '6'), ('ORACLE', '7')]

如果您想以您提供的格式将它们收集到字符串列表中,只需替换

res.extend((key, v) for v in values[1:])

res.extend('{},{}'.format(key, v) for v in values[1:])

【讨论】:

  • 我正在从文件中读取数据。这被读入 RDD f = sc.textFile("data/text.data")。 splitlines 不适用于 rdd。我得到一个错误'RDD'对象没有属性'splitlines'
  • @KC,我不知道 RDD 是什么。 splitlines()str 的方法。我用它来遍历字符串中的行。我猜,你可以用for line in f 遍历文件中的行。无论如何,找到一种方法逐行读取此文件并用正确的代码替换for line in inp.splitlines():
【解决方案2】:

使用flatMap()

data_rdd.flatMap(lambda row: [ 
    (k, v) for k, vs in [row.replace('"','').split(',', 1)] for v in vs.split(',')
]).collect() 

#[('SQL', '1'),
# ('SQL', '2'),
# ('SQL', '3'),
# ('SQL', '4'),
# ('SQL', '5'),
# ('ORACLE', '2'),
# ('ORACLE', '5'),
# ('ORACLE', '6'),
# ('ORACLE', '7')]

地点:

  1. [row.replace('"','').split(',', 1)] 将像 "SQL",1,2,3,4,5 这样的行转换为两个元素的列表 SQL1,2,3,4,5
  2. vs.split(',') 然后将第二项拆分为新列表
  3. 包含 (k, v) 元组的列表推导将被 flatMap() 展平

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多