• Tablesaw——Java数据框架和可视化库,Java中的 “Pandas”


    一. 前言

    Tablesaw是一款Java的数据可视化库,主要包括两部分:

    1. 数据解析库,主要用于加载数据,对数据进行操作(转化,过滤,汇总等),类比Python中的Pandas库;
    2. 数据可视化库,将目标数据转化为可视化的图表,类比Python中的Matplotlib库。

    与Pandas不同的是,Tablesaw中的表格以列(Column)为基本单位,因此大部分操作都是基于列进行的。当然也包括部分对行操作的函数,但是功能比较有限。

    首先我们看一下Tablesaw支持的导入和导出文件的类型:
    在这里插入图片描述

    官方教程几乎包括了所有的操作:https://jtablesaw.github.io/tablesaw/userguide/toc,下面我就介绍一下我在写项目中使用到的一些操作。

    二. Maven导入包

    <dependency>
        <groupId>tech.tablesaw</groupId>
        <artifactId>tablesaw-core</artifactId>
        <version>LATEST</version>
    </dependency>
    	
    <dependency>
      	<groupId>tech.tablesaw</groupId>
      	<artifactId>tablesaw-excel</artifactId>
      	<version>LATEST</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    三. 基本操作

    3.1 列操作

    Tablesaw中的列包括很多种数据类型,常用的包括:字符串列(StringColumn)、整型列(IntColumn)、浮点列(DoubleColumn)、日期时间列(DateTimeColumn)等,每一种列提供的API都大同小异。

    3.1.1 创建列

    /*1. 创建一个空列*/
    DoubleColumn column = DoubleColumn.create("column name");
    /*2. 创建一个有初始值的列*/
    double[] values = {1, 2, 3, 7, 9.44242, 11};
    DoubleColumn column = DoubleColumn.create("column name", values);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.1.2 添加、编辑和删除数据

    /*添加数据*/
    column.append(value)
    /*编辑数据*/
    doubleColumn.set(index, value);
    /*删除数据*/
    //方式1
    column.setMissing(0);
    column = column.removeMissing();
    //方式2
    //这里用到了后面过滤的api
    column.setMissing(index);
    Selection sl = column.isNotMissing();
    column = column.where(sl);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.1.3 通用api

    name()                  // 返回列名
    type()                  // 返回列的数据类型,比如LOCAL_DATE
    size()                  // 返回列的长度
    isEmpty()               // 返回列是否为空
    first(n) and last(n)    // 返回列前/后n个数
    max() and min()         // 返回列的最大值/最小值
    top(n) and bottom(n)    // 返回n个最大/最小的数
    print()                 // 返回列的字符串类型,用于输出
    copy()					// 复制一份新列
    unique()				// 返回列中的元素并只出现一次
    countUnique()			// 返回列中元素的种类
    void sortAscending()	// 升序排列
    void sortDescending()	// 降序佩列  
    append(otherColumn)     // 将其他列添加到这个列后面
    removeMissing()			// 返回去除missing元素后的列
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.1.4 筛选

    3.1.4.1 筛选出想要的列

    筛选可以说是最重要的操作之一,它可以帮助我们选出我们想要的元素。以下面这个列为例:

    double[] values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    DoubleColumn column = DoubleColumn.create("column name", values);
    
    • 1
    • 2
    Column: column name
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    筛选的第一步操作是创建一个表达式,比如我想筛选出所有大于5的数:

    Selection limit = column.isGreaterThan(5);
    
    • 1

    然后就可以用where(Selection)函数进行筛选:

    DoubleColumn column_new = column.where(limit);
    
    • 1
    Column: column name
    6
    7
    8
    9
    10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Tablesaw提供了非常多的表达式,几乎可以满足我们所有的需求:
    在这里插入图片描述
    对于DateColumnDateTimeColumn这种时间相关的列而言,他们有一些特殊的表达式:
    在这里插入图片描述
    它可以帮助我们筛选出我们想要的日期,同时我们也可以通过先获取日期列的年/月/日/时/分/秒来得到一个新的列,再对列进行筛选。比如我想筛选出所有凌晨6点-7点的时间:

    datetimecolumn.hour().isEqualTo(6);
    
    • 1

    列筛选是表格筛选的基础,后面还会继续讲解如何进行表格筛选。

    3.1.4.2 有条件的编辑数据

    以下面这个列为例:

    double[] values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    DoubleColumn column = DoubleColumn.create("column name", values);
    
    • 1
    • 2

    比如我们想替换所有大于5的数为100,那么可以:

    Selection limit = doublecolumn.isGreaterThan(5);
    doublecolumn.set(limit, 100.0);
    
    • 1
    • 2

    比如我们可以将所有缺失值设置为平均值:

    double avg = doubleColumn.mean();
    doubleColumn.set(doubleColumn.isMissing(), avg)
    
    • 1
    • 2

    3.1.5 输出列

    将列输出到终端显示:

    System.out.println(doublecolumn.print());
    
    • 1

    3.2 表格操作

    Tablesaw有大量创建、查询、操作、显示和保存表的方法,而且对表的许多操作都会返回其他表。例如,当您要求一个表描述其结构时,它会返回一个包含列名、类型和顺序的新表。

    3.2.1 创建表格(导入文件)

    /*方式一:添加列到表格中*/
    Table t = Table.create("name", column1, column2, column3...)
    //比如:
    double[] values1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    DoubleColumn column1 = DoubleColumn.create("column1", values1);
    double[] values2 = {2, 1, 4, 4, 5, 6, 6, 1, 8, 4};
    DoubleColumn column2 = DoubleColumn.create("column2", values2);
    
    /*方式二:从文件中导入*/
    Table t = Table.read().csv("myFile.csv");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    当我们想从文件中导入表格时,我建议采用以下方法:

    Table.read().file(File file);
    Table.read().file(String path);
    
    • 1
    • 2

    采用这种方式可以既可以导入.csv格式的文件,也可以导入.xlsx.xls格式的文件,但是这种方式不能指定导入文件的sheet,如果想要指定sheet,采用下面这种方法:

    Table cap = Table.read().usingOptions(XlsxReadOptions
    									.builder(String path)
    									.sheetIndex(String sheet));
    
    • 1
    • 2
    • 3

    3.2.2 添加、删除和选择列

    3.2.2.1 添加列

    可以使用向表中添加一列或多列addColumns()方法:

    t.addColumns(aColumn...)
    
    • 1

    还可以通过提供索引来指定在特定位置插入列:

    t.addColumn(3, aColumn);
    
    • 1

    需要注意的是,新添加的列必须为空,或者与表中的其他列具有相同数量的元素。

    3.2.2.2 删除列

    要删除一列或多列:

    t.removeColumns(int... columnindexes)
    t.removeColumns(String... columnnames)
    
    • 1
    • 2

    或者指定想要保存的列,删除其他列,但是这种操作会在原列上进行,如果想要选择某几列而不改变原始数据,建议使用下面的选择列

    t.retainColumns(int... columnindexes)
    t.retainColumns(String... columnnames)
    
    • 1
    • 2

    3.2.2.3 选择列

    当前官方文档中选择列给的是select()函数,但是我建议使用selectColumns(),因为前者不能通过指定index来选择列,而后者既可以用名称选择也可以用index选择:

    Table t2 = t.selectColumns("column1");
    Table t2 = t.selectColumns(0);
    
    • 1
    • 2

    也可以通过在当前表格中指定不需要的列来创建新表格,这可能会节省一些键入时间,同样这个函数也可以用名称和index来指定列:

    Table t2 = t.rejectColumns("column1");
    Table t2 = t.rejectColumns(0);
    
    • 1
    • 2

    如果只选择一列,通常需要将返回的列转换为更具体的类型。例如:

    DoubleColumn dc = t.doubleColumn();
    
    • 1

    3.2.3 拼接表格

    拼接表格有两种形式,一种是横向拼接,也就是行数相同,增加列数;零一周是纵向拼接,也就是列数相同,增加行数。

    /*1. 横向组合*/
    Table result = t.concat(t2);
    /*2. 纵向组合*/
    Table result = t.append(t2);
    
    • 1
    • 2
    • 3
    • 4

    需要注意的是,横向拼接时两个表格的列名不能有重复,纵向拼接时对应列的列名必须相同。

    3.2.4 筛选

    筛选是在列筛选的基础上进行的,我们以下面这个表格为例:

    LocalDate currentdate = LocalDate.of(Integer.parseInt("2022"), 1, 1);
    List<LocalDate> date_list = new ArrayList<LocalDate>();
    for(int d=0;d<10;d++)
    {
    	date_list.add(currentdate.plusDays(d));
    }
    DateColumn date = DateColumn.create("Time", date_list);
    		
    double[] values = {1, 2, 3, 4, 5,6,7,8,9,10};
    DoubleColumn value = DoubleColumn.create("value", values);
    		
    Table t = Table.create("a",date,value);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
               a            
        Time     |  value  |
    ------------------------
     2022-01-01  |      1  |
     2022-01-02  |      2  |
     2022-01-03  |      3  |
     2022-01-04  |      4  |
     2022-01-05  |      5  |
     2022-01-06  |      6  |
     2022-01-07  |      7  |
     2022-01-08  |      8  |
     2022-01-09  |      9  |
     2022-01-10  |     10  |
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这里将筛选出2022年1月5日以后的数据。

    筛选的第一步是选择我们想要筛选的列:

    DateColumn date_column = t.dateColumn(0);
    
    • 1

    第二步是创建一个约束的表达式:

    Selection limit = date_column.dayOfMonth().isGreaterThan(5);
    
    • 1

    第三步就可以用where()函数进行筛选了:

    Table t2 = t.where(limit);
    
    • 1
               a            
        Time     |  value  |
    ------------------------
     2022-01-06  |      6  |
     2022-01-07  |      7  |
     2022-01-08  |      8  |
     2022-01-09  |      9  |
     2022-01-10  |     10  |
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    筛选时我们也可以同时指定多个约束,比如我想要筛选出2022年1月5日以后并且value大于7的数据:

    DateColumn date_column = t.dateColumn(0);
    Selection limit1 = date_column.dayOfMonth().isGreaterThan(5);
    DoubleColumn value_column = t.doubleColumn(1);
    Selection limit2 = value_column.isGreaterThan(7);
    Table t2 = t.where(limit1.and(limit2));
    
    • 1
    • 2
    • 3
    • 4
    • 5
               a            
        Time     |  value  |
    ------------------------
     2022-01-08  |      8  |
     2022-01-09  |      9  |
     2022-01-10  |     10  |
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.2.5 输出表格

    将表格输出到终端显示:

    System.out.println(t.print());
    
    • 1

    3.2.6 导出表格

    table.write().csv("filename.csv");
    
    • 1

    表格只能导出为.csv格式,后面我会写一下如何利用EasyExcel库将.csv文件另存为.xlsx中的某个sheet当中。

    四. 最后

    本文介绍了Tablesaw中的一些常用的基本操作,这些操作基本上能满足我们工作中的大部分需求,如果有其他需要可以去官网上查找对应的方法。总而言之Tablesaw是一个非常强大的数据处理库,但是也有一些不足之处,比如无法导出.xlsx格式的文件。目前这个库应该还在不断完善当中,期待Tablesaw能够实现更多的功能!

  • 相关阅读:
    1.jetson与摄像头的对接
    原型、原型链、判断数据类型
    【IC设计】Chisel开发环境搭建
    Linux 查看端口占用情况
    没有展会,外贸人还可以怎么高效获客?
    geoserver多种数据源图层发布详解
    并发原子类
    Asp.Net Core服务端处理请求过来的压缩格式
    2.树莓派4b+ubuntu18.04(ros版本melodic)+arduino mega自制两轮差速小车,实现建图导航功能
    Scala网络编程:代理设置与Curl库应用实例
  • 原文地址:https://blog.csdn.net/cyj972628089/article/details/126127748