如何在HadoopMapReduce中比较同一文件中的数据?

ovfsdjhp  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(331)

我有这样一个数据集:

X, Y, Text  
52.2552455,-7.5450262,donec
57.6727414,-4.269928,nulla
13.0504833,50.3308509,curae
25.6538807,58.263232,magna
30.292001,57.8308498,massa
37.9273983,41.107107,mauris
37.444498,2.9372148,volutpat
``` `X,Y` 值(经度、纬度)表示一个“点”。
我想在这里实现的是将每个x,y(作为一个值键)按它们之间的距离分组比较。
输出应为:

52.2552455,-7.5450262 [nulla,curae,mauris]
57.6727414,-4.269928, [curae,massa]
13.0504833,50.3308509, [massa]
25.6538807,58.263232, [volutpat,magna,mauris]
30.292001,57.8308498, [mauris]
37.9273983,41.107107, [mauris,volutpat,magna,curae]
37.444498,2.9372148, [volutpat]

输出意味着:52.2552455,-7.5450262与这些字符串(nulla、curae、mauris)相邻。
对于数据集中的所有x,y也是如此。
我已经写了下面的代码:

public static class Map extends Mapper<LongWritable, Text, Text, Text>
{
double spotX = 48.5672;
double spotY = 35.6897;
String tweet = "";
private int distX= 20;
private int distY= 20;
private Text key1 = new Text();
private Text value1 = new Text();

public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException 
    {   

        String line = value.toString();
        String[] results = line.split(",");

        for(int i=0; i < results.length; i+=3)
            {   

                if (Double.parseDouble(results[i]) - spotX >= distX || Double.parseDouble(results[i+1]) - spotY >= distY )
                {

                    key1.set(spotX + "," + spotY);
                    value1.set(results[i] + "," + results[i+1]+ "," +results[i+2]);
                    context.write(key1,value1); 
                }
                else
                {
                    break;
                }

            }
    }           
}

public static class Reduce extends Reducer<Text, Text, Text, Text>
{

 public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException 
 {   

    List<String> vArrayList = new ArrayList<String>();
    for(Text v : values)
    {
        vArrayList.add(v.toString());
    }
    context.write(key, new Text(vArrayList.toString()));             
 }

}

目前我的代码只能将所有“spots”与静态spotx进行比较,spoty在map函数中声明。
有没有办法让我有一个动态的spotx,spoty?我的意思是,每一行,声明它是一个比较与其他?
我希望我说得够清楚。
2q5ifsrm

2q5ifsrm1#

为了使你想要的成为可能,你必须一次读整个文件。不能使用默认值 TextInputFormat 在输入文件的新行上拆分的。
您可以找到 WholeFileInputFormat 在这里。
http://bigdatathinker.blogspot.com/2014/01/reading-complete-file-in-mapreduce.html
你会把它用在你的生活中 Job 主方法的配置。看起来链接的输入格式的关键是 Text ,但值为 BytesWritable . 你可以找到其他的例子,我肯定能看完所有的文件。
您希望在Map程序中获得的结果 "X, Y, Text\n52.2552455,-7.5450262,donec \n57.6727414,-4.269928,nulla" ,(一个长字符串)作为要处理的数据。
从那里,你可以 value.split("\\n") ,并遍历这些线,在拥有所有数据点的情况下相应地进行距离计算。
总而言之,在这里使用hadoop没有任何好处,因为1)您的数据集看起来很小2)它只不过是一个java进程自己读取文件。
你可能想研究的是k-均值聚类,因为我认为这正是你想要的。

相关问题