我有一个看起来像这样的数据集:
drawdate lotterynumbers meganumber multiplier
2005-01-04 03 06 07 12 32 30 NULL
2005-01-07 02 08 14 15 51 38 NULL
etc.
和以下代码:
public class LotteryCount {
/**
* Mapper which extracts the lottery number and passes it to the Reducer with a single occurrence
*/
public static class LotteryMapper extends Mapper<Object, Text, IntWritable, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private IntWritable lotteryKey;
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString(), ",");
while (itr.hasMoreTokens()) {
lotteryKey.set(Integer.valueOf(itr.nextToken()));
context.write(lotteryKey, one);
}
}
}
/**
* Reducer to sum up the occurrence
*/
public static class LotteryReducer
extends Reducer<IntWritable, IntWritable, IntWritable, IntWritable> {
IntWritable result = new IntWritable();
public void reduce(IntWritable key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
}
它实际上是官方apache hadoop文档中的字数统计,只是根据我的数据集定制了一点。
我得到以下错误:
Caused by: java.lang.NumberFormatException: For input string: "2005-01-04"
我只对计算每个抽到的彩票号码的出现次数感兴趣。我如何使用代码中的StringTokenizer来做到这一点?我知道我必须拆分整行因为标记器是"与整体。我怎样才能把彩票号码分开,然后再数呢?
提前谢谢你
我只是对计算每个抽到的彩票号码的出现次数感兴趣。我如何使用代码中的StringTokenizer来做到这一点?我知道我必须拆分整行因为标记器是"与整体。我怎样才能把彩票号码分开,然后再数呢?
您发布的数据示例是:
drawdate lotterynumbers meganumber multiplier
2005-01-04 03 06 07 12 32 30 NULL
2005-01-07 02 08 14 15 51 38 NULL
下面是一个简单的例子,还有一些注意事项:
- 这将使用示例数据的第一行作为
line
,包括分隔数据字段的制表符,就像您发布的一样。 - 它使用
StringTokenizer
,令牌分隔符定义为单个制表符(t
) - 程序调用
hasMoreTokens()
,直到看到所有令牌,一路上打印每个令牌。 - 输出包括左+右括号,以显示每个令牌的边界。例如,"30";有一个尾部空格字符,如果不使用
[]
字符就不会被注意到,与&;null &;前面的前导空格相同。
String line = "2005-01-04 03 06 07 12 32 30 NULL";
StringTokenizer tokenizer = new StringTokenizer(line, "t");
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
System.out.println("token: [" + token + "]");
}
输出如下:
token: [2005-01-04 ]
token: [03 06 07 12 32 ]
token: [30 ]
token: [ NULL]
您可以采用这种方法,处理所有行,标记制表符,并使用第二个标记作为您的"lotterynumbers"数据做你喜欢的事。
第一个问题-在传递给MapReduce之前,您需要删除文件的头。
第二-你在显示的数据集中没有逗号,所以","
不应该给StringTokenizer
。试着用"t"
代替
Next -不是所有的令牌都是整数,所以盲目调用Integer.valueOf(itr.nextToken())
是行不通的。第一列是日期。您可以在循环之前调用itr.nextToken()
以丢弃日期,但随后需要在末尾处理NULL
。