【问题标题】:Controlling python outputs to console控制 python 输出到控制台
【发布时间】:2017-09-30 20:14:31
【问题描述】:

我正在使用 Hadoop/MapReduce 构建电影推荐。
现在我只使用 python 来实现 MapReduce 过程。

所以我基本上做的是分别运行每个映射器和减速器,并使用从映射器到减速器的控制台输出。

我遇到的问题是 python 在终端中将值输出为字符串,所以如果我使用数字,数字将打印为字符串,这使得简化过程变得困难,因为它的转换增加了更多加载到服务器上。

那么我该如何解决这个问题,我希望使用纯 python 来实现它,而不是使用 3rd-party 库。

import sys

def mapper():
    '''
        From Mapper1 : we need only UserID , (MovieID , rating)
        as output.
    '''

    #* First mapper

    # Read input line
    for line in sys.stdin:
        # Strip whitespace and delimiter - ','
        print line
        data = line.strip().split(',')

        if len(data) == 4:
            # Using array to print out values
            # Direct printing , makes python interpret
            # values with comma in between as tuples
            # tempout = []
            userid , movieid , rating , timestamp = data
            # tempout.append(userid)
            # tempout.append((movieid , float(rating)))
            # print tempout

            #
            print "{0},({1},{2})".format(userid , movieid , rating)

这是 reducer 打印语句:

def reducer():

    oldKey = None
    rating_arr = []

    for line in sys.stdin:
        # So we'll recieve user, (movie,rating)
        # We need to group the tuples for unique users
        # we'll append the tuples to an array
        # Given that we have two data points , we'll split the
        # data at only first occurance of ','
        # This splits the string only at first comma

        data = line.strip().split(',',1)
        # print len(data) , data
        # check for 2 data values
        if len(data) != 2:
            continue

        x , y = data

        if oldKey and oldKey != x:

            print "{0},{1}".format(oldKey , rating_arr)
            oldKey = x
            rating_arr = []
        oldKey = x
        rating_arr.append(y)
        # print rating_arr
    if oldKey != None:
        print "{0},{1}".format(oldKey , rating_arr)

`

输入是:

671,(4973,4.5)\n671,(4993,5.0)\n670,(4995,4.0)

输出是:

671,['(4973,4.5)', '(4993,5.0)']
670,['(4995,4.0)']

我需要元组,没有字符串。

【问题讨论】:

  • Python 不会自动将列表中的元组转换为字符串,看来您的问题出在上游。
  • 这里有很多缺失的代码。没有它,我们就没有多大用处。
  • 请检查更新后的代码
  • 请显示你想要的输出
  • @cricket_007 元组的值被转换为字符串。 ,我需要整数值

标签: python hadoop mapreduce hadoop-streaming


【解决方案1】:

事实上,数据是一个字符串,然后您将其拆分并分配y 给它,它仍然是一个字符串

如果你想要元组的原始值,作为数字,你需要解析它们。

ast.literal_eval 可以提供帮助。

例如,

In [1]: line = """671,(4973,4.5)"""

In [2]:  data = line.strip().split(',',1)

In [3]: data
Out[3]: ['671', '(4973,4.5)']

In [4]: x , y = data

In [5]: type(y)
Out[5]: str

In [6]: import ast

In [7]: y = ast.literal_eval(y)

In [8]: y
Out[8]: (4973, 4.5)

In [9]: type(y)
Out[9]: tuple

In [10]: type(y[0])
Out[10]: int

现在,如果您想切换到 PySpark,您可以更好地控制变量/对象类型,而不是使用 Hadoop Streaming 的所有字符串

【讨论】:

  • 对不起,但它似乎不起作用,它给出了格式错误的字符串错误。括号似乎是个问题。将其转换为 str 然后使用 literal_eval 仍将列表中的值解释为 string ,请参阅撇号。还有什么我应该尝试的吗?有没有办法在不同的mapper和reducer之间直接传递数据?
  • 显然print "%d"%rating_arr 不起作用,因为数组不是d十进制数。你需要直接print rating_arr
  • 然而,你的 reducer 应该有一致的输出。所以你可以再次使用print "{0},{1}".format(oldKey , rating_arr),这取决于你需要做什么
  • 是的,打印直接将其转换为 str ,这就是问题。尝试在此处运行 reducer 代码,并查看输出。 github.com/PadamSethia/hadoopwithpy/blob/master/Recommender/…
  • 知道了,谢谢!附加到列表时,我在值上使用了 ast。
猜你喜欢
  • 2018-05-26
  • 1970-01-01
  • 2013-03-18
  • 2011-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多