如何减少python

时间:2017-12-13 02:39:58

标签: python python-2.7 mapreduce

我有一个数组,我想计算数组中每个项目的出现次数。

我已设法使用map函数生成元组列表。

def mapper(a):
    return (a, 1)

r = list(map(lambda a: mapper(a), arr));

//output example: 
//(11817685, 1), (2014036792, 1), (2014047115, 1), (11817685, 1)

我期望reduce函数可以帮助我按每个元组中的第一个数字(id)对计数进行分组。例如:

(11817685, 2), (2014036792, 1), (2014047115, 1)

我试过

cnt = reduce(lambda a, b: a + b, r);

和其他一些方法,但他们都没有做到这一点。

注意 感谢关于解决问题的其他方法的所有建议,但我只是学习Python以及如何在这里实现map-reduce,并且我已经简化了我的实际业务问题以使其易于理解,所以请善意告诉我一个正确的map-reduce方法。

4 个答案:

答案 0 :(得分:5)

您可以使用Counter

from collections import Counter
arr = [11817685, 2014036792, 2014047115, 11817685]
counter = Counter(arr)
print zip(counter.keys(), counter.values())

修改

正如@ShadowRanger Counter所指出的那样items()方法:

from collections import Counter
arr = [11817685, 2014036792, 2014047115, 11817685]
print Counter(arr).items()

答案 1 :(得分:1)

您可以使用某些逻辑而不使用任何模块来代替使用任何外部模块:

track={}
if intr not in track:
    track[intr]=1
else:
    track[intr]+=1
  

示例代码:

对于这些类型的列表问题,有一种模式:

假设你有一个清单:

a=[(2006,1),(2007,4),(2008,9),(2006,5)]

并且你希望将它转换为dict作为元组的第一个元素作为元组的键和第二个元素。类似的东西:

{2008: [9], 2006: [5], 2007: [4]}

但是有一个问题,你也想要那些具有不同值但键相同的键,如(2006,1)和(2006,5)键是相同的,但值是不同的。你希望那些值只附加一个键,所以预期输出:

{2008: [9], 2006: [1, 5], 2007: [4]}

对于这类问题,我们会这样做:

首先创建一个新的字典然后我们遵循这种模式:

if item[0] not in new_dict:
    new_dict[item[0]]=[item[1]]
else:
    new_dict[item[0]].append(item[1])

因此我们首先检查密钥是否在新的dict中,如果已经存在,则将duplicate key的值添加到其值中:

完整代码:

a=[(2006,1),(2007,4),(2008,9),(2006,5)]

new_dict={}

for item in a:
    if item[0] not in new_dict:
        new_dict[item[0]]=[item[1]]
    else:
        new_dict[item[0]].append(item[1])

print(new_dict)

输出:

{2008: [9], 2006: [1, 5], 2007: [4]}

答案 2 :(得分:0)

如果你需要的只是cnt,那么dict可能比list tuple更好(如果你需要这种格式,只需使用{ {1}})。

dict.items模块有一个有用的数据结构,collections

defaultdict

答案 3 :(得分:0)

my answer写入a different question后,我记得这篇文章,并认为在此处写一个类似的答案会有所帮助。

这是一种在列表中使用reduce来获得所需输出的方法。

arr = [11817685, 2014036792, 2014047115, 11817685]

def mapper(a):
    return (a, 1)

def reducer(x, y):
    if isinstance(x, dict):
        ykey, yval = y
        if ykey not in x:
            x[ykey] = yval
        else:
            x[ykey] += yval
        return x
    else:
        xkey, xval = x
        ykey, yval = y
        a = {xkey: xval}
        if ykey in a:
            a[ykey] += yval
        else:
            a[ykey] = yval
        return a

mapred = reduce(reducer, map(mapper, arr))

print mapred.items()

打印哪些:

[(2014036792, 1), (2014047115, 1), (11817685, 2)]

请参阅linked answer以获取更详细的说明。