我正在努力实现我认为应该非常简单但我无法通过思考,因此需要一些帮助。
我有一个RDD,我有:
key1, (val_id1,val11), (val_id2,val12),(val_id3,val13) ...
key2, (val_id5,val25), (val_id7,val27), (val_id2,val22) ...
...
我想为每个键,所有值对的组合使得值元组中的第二个元素在输出之前相乘。例如:
上面key1的值产生的输出是:
((val_id1,val_id2), val11 * val12) , ((val_id1,val_id3),val11 * val13) , ((val_id2,val_id3),val12 * val13) ...
我知道itertools包中有一个itertools.combinations模块,但我不知道如何将它完全合并到RDD的上下文中。任何帮助将非常感激。
答案 0 :(得分:2)
假设原始RDD是文本格式。以下代码尚未在spark上运行,但解决方案应该是这样的。
from itertools import combinations
import re
def clean(dirtyRecord):
"""
Accept a String value "key1, (val_id1,key11), (val_id2,key22), ..."
and convert it into record of the form
[key1, [(val_id1, key11), (val_id2, key12), ... ]]
"""
splitRecord = dirtyRecord.split(', ')
# The splitRecord[0] is the 'key'
splits = [re.search('\((\w+),(\w+)\)', tuples).groups() for tuples in splitRecord[1:]]
updateSplitsWithFloat = []
for item in splits:
updateSplitsWithFloat.append((item[0], float(item[1]))
splits = splitRecord[0] + updateSplitsWithFloat
return splits
def genCombinations(features):
"""
Accept a list [(val_id1, key11), (val_id2, key12), ... ]
and generate the output asked in question
"""
val_ids, vals = zip(*features)
val_ids = combinations(val_ids, repeat=2)
vals = map(lambda x: x[0] * x[1], combinations(vals, repeat=2))
return [(t0, t1) for t0, t1 in zip(val_ids, vals)]
# Begin processing the original data
valuesPerKeyRDD = (originalRawRDD
.map(lambda x: clean(x))
.map(lambda x: (x[0], genCombinations(x[1])))
.cache())
答案 1 :(得分:0)
这是函数(它假设内部集合是字典,因为它们应该是。但是如果你没有它,你总是可以将.keys()函数替换为你需要循环遍历内部元组列表的地方。拿回钥匙)
def get_res(tup):
based_dict = tup[1]
k = tup[0]
generated_tupes = []
for comb in itertools.combinations(based_dict.keys(),2):
value = str(based_dict[comb[0]])+"**"+str(based_dict[comb[1]])
generated_tupes.append((comb,value))
return (k,generated_tupes)
你可以在没有火花的情况下进行测试:
>>> based
[('k1', {'id2': 12, 'id3': 13, 'id1': 11}), ('k2', {'id4': 24, 'id5': 25})]
>>> transformed = map(get_res,based)
>>> transformed
[('k1', [(('id2', 'id3'), '12**13'), (('id2', 'id1'), '12**11'), (('id3', 'id1'), '13**11')]), ('k2', [(('id4', 'id5'), '24**25')])]
在你的火花代码中,只需调用rdd.map(get_res)
即可答案 2 :(得分:0)
我已经制定了此算法,但是使用更高的数字似乎无法正常工作或运行速度很慢,它将在大数据集群(cloudera)中运行,因此我认为我必须将函数放入pyspark ,请帮忙。
将熊猫作为pd导入 将itertools导入为its
number_list = [10953,10423,10053]
def reducer(nums): 定义范围(n): 打印(n) 返回范围(n,-1,-1)
num_list = list(map(ranges,nums)) 返回列表(itts.product(* num_list))
data = pd.DataFrame(reducer(number_list)) 打印(数据)