使用Java和Python进行数据统计和剖析
发布时间:2022-06-25 12:57 所属栏目:125 来源:互联网
导读:Java 和 Python 是当今最流行的两种计算机语言。两者都非常成熟,并提供了工具和技术生态系统,帮助我们解决数据科学领域出现的挑战性问题。每种语言都各有优势,我们要知道什么时候应该使用哪种工具,或者什么时候它们应该协同工作相互补充。 Python 是一种
Java 和 Python 是当今最流行的两种计算机语言。两者都非常成熟,并提供了工具和技术生态系统,帮助我们解决数据科学领域出现的挑战性问题。每种语言都各有优势,我们要知道什么时候应该使用哪种工具,或者什么时候它们应该协同工作相互补充。 Python 是一种动态类型语言,使用起来非常简单,如果我们不想接触复杂的程序,它肯定是进行复杂计算的首选语言。Python 提供了优秀的库(Pandas、NumPy、Matplotlib、ScyPy、PyTorch、TensorFlow 等)来支持对数据结构或数组的逻辑、数学和科学操作。 Java 是一种非常健壮的语言,具有强类型,因此有更严格的语法规则,所以不易出现程序错误。与Python一样,它也提供了大量的库来处理数据结构、线性代数、机器学习和数据处理(ND4J、Mahout、Spark、Deeplearning4J 等)。 本文将介绍如何对大量表格数据进行简单的数据分析,并使用 Java 和 Python 计算一些统计数据。我们可以看到使用各个平台进行数据分析的不同技术,对比它们的扩展方式,以及应用并行计算来提高其性能的可行性。 首先定义一个封装数据元素的 Java 记录: 复制 record InputEntry(String city, String state, double basePrice, double actualPrice) {} 1. 记录(record)是 JDK 14 中引入的一种新型类型声明。它是定义提供构造函数、访问器、equals 和哈希实现的不可变类的一种简捷方式。 接下来,读取 CVS 文件并将它们增加到一个列表中: 复制 List<InputEntry> inputEntries = readRecordEntriesFromCSVFile(recordEntries.csv); 1. 为了按城市和州对输入的元素进行分组,将其定义: 复制 record CityState(String city, String state) {}; 1. 使用以下类来封装属于一个组的所有元素的统计信息: 复制 record StatsAggregation(StatsAccumulator basePrice, StatsAccumulator actualPrice) {} 1. StatsAccumulator是Guava 库的一部分。可以将双精度值集合添加到类中,它会计算基本统计数据,例如计数、平均值、方差或标准差。可以使用StatsAccumulator来获取InputEntry的basePrice和actualPrice的统计数据。 现在我们已经拥有了解决问题的所有材料。Java Streams提供了一个强大的框架来实现数据操作和分析。它的声明式编程风格,对选择、过滤、分组和聚合的支持,简化了数据操作和统计分析。它的框架还提供了一个强大的实现,可以处理大量的(甚至是无限的流),并通过使用并行性、懒惰性和短路操作来高效处理。所有这些特性使Java Streams成为解决这类问题的绝佳选择。实现非常简单: 复制 Map<CityState, StatsAggregation> stats = inputEntries.stream(). filter(i -> !(i.state().equals("MN") || i.state().equals("CA"))).collect( groupingBy(entry -> new CityState(entry.city(), entry.state()), collectingAndThen(Collectors.toList(), list -> {StatsAccumulator sac = new StatsAccumulator(); sac.addAll(list.stream().mapToDouble(InputEntry::basePrice)); StatsAccumulator sas = new StatsAccumulator(); sas.addAll(list.stream().mapToDouble(InputEntry::actualPrice)); return new StatsAggregation(sac, sas);} ))); 在代码的第 2 行,我们使用Stream::filter. 这是一个布尔值函数,用于过滤列表中的元素。可以实现一个 lambda 表达式来删除任何包含“MN”或“CA”状态的元素。 然后继续收集列表的元素并调用Collectors::groupingBy()(第 3 行),它接受两个参数: 一个分类功能,使用CityState记录来做城市和州的分组(第3行)。 下游的收集器,包含属于同一<城州>的元素。使用Collectors::collectingAndThen(第 4 行),它采用两个参数分两步进行归约: ·我们使用Collectors::toList(第 4 行),它返回一个收集器,它将属于同一<城州>的所有元素放到一个列表中。 ·随后对这个列表进行了整理转换。使用一个lambda函数(第5行至第9行)来定义两个StatsAccumulator(s),在这里分别计算前一个列表中的basePrice和actualPrice元素的统计数据。最后,返回到新创建的包含这些元素的StatsAggregation记录。 正如前文所述,使用Java Streams的优势之一是,它提供了一种简单的机制,可以使用多线程进行并行处理。这允许利用CPU的多核资源,同时执行多个线程。只要在流中添加一个 "parallel": 复制 Map<CityState, StatsAggregation> stats = inputEntries.stream().parallel(). 1. 这导致流框架将元素列表细分为多个部分,并同时在单独的线程中运行它们。随着所有不同的线程完成它们的计算,框架将它们串行添加到生成的 Map 中。 在第4行中使用Collectors::groupingByConcurrent而不是Collectors:groupingBy。在这种情况下,框架使用并发映射,允许将来自不同线程的元素直接插入到此映射中,而不必串行组合。 (编辑:ASP站长网) |
相关内容
网友评论
推荐文章
热点阅读