我有一个大型CSV文件,其数据与此类似
User ID Group
ABC Group1
DEF Group2
ABC Group3
GHI Group4
XYZ Group2
UVW Group5
XYZ Group1
ABC Group1
DEF Group2
我需要对这些项目进行分组,以便在用户ID中重复组属性的次数,并获得一个值
ABC Group1 ->2
ABC Group3 ->1
DEF Group2 ->2
GHI Group4 ->1
UVW Group5 ->1
XYZ Group2 ->1
XYZ Group1 ->1
是否有任何聚类算法可以做到这一点。
答案 0 :(得分:1)
一个非常简单的解决方案是使用Guava的TreeMultiset:http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/TreeMultiset.html。
使用字段userId和group创建一个类UserGroup,并通过首先在userId上进行比较然后在group上进行比较,让它实现Comparable。
读入csv文件,每行创建一个UserGroup并将其添加到MultiSet,
要获得结果,请使用MultiSet.iterator(),并输入entry.getElement()和entry.getCount()。
如果您获得内存不足,并且无法分配足够的内存,则可以使用外部(合并)排序https://code.google.com/p/externalsortinginjava/
答案 1 :(得分:1)
在你的情况下,如果你不想将所有数据存储在内存中,我会做这样的事情:
public class Tester {
public static Multiset<String> getMultisetFromCSV(String csvFileName, String lineDelimiter) throws IOException {
Multiset<String> mapper = TreeMultiset.create();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(csvFileName));
String[] currLineSplitted;
while(reader.ready()) {
currLineSplitted = reader.readLine().split(lineDelimiter);
mapper.add(currLineSplitted[0] + "-" + currLineSplitted[1]);
}
return mapper;
} finally {
if(reader != null)
reader.close();
}
}
public static void main(String[] args) throws IOException {
Multiset<String> set = getMultisetFromCSV("csv", ",");
for(String key : set.elementSet()) {
System.out.println(key + " : " + set.count(key));
}
}
}
通过这种方式,您可以非常轻松地构建地图。之后,对于每个键,您可以使用count method计算与其关联的项目数。
答案 2 :(得分:1)
使用Java 8,您可以编写如下内容:
Map<String, Long> userGroup = Files.lines(csvFile, UTF_8)
.skip(1) //skip headers
.map(s -> s.split("\\s+")) //split on space
.map(array -> array[0] + " " + array[1]) //user + " " + group
//collect into a TreeMap, for sorting
//the key is the user/group and the value the number of occurences
.collect(groupingBy(ug -> ug, TreeMap::new, counting()));
注意:需要以下静态导入:import static java.util.stream.Collectors.counting;
和import static java.util.stream.Collectors.groupingBy;