update DataFrame IO functions

This commit is contained in:
wyq 2025-10-01 11:07:28 +08:00
parent 42153c5bc0
commit 07e26a4fc3
5 changed files with 159 additions and 75 deletions

View File

@ -24,7 +24,7 @@ public class Column {
protected String name;
protected DataType dataType;
protected String format;
protected DateTimeFormatter dateTimeFormatter;
protected String printFormat;
protected int formatLen;
// </editor-fold>
// <editor-fold desc="Constructor">
@ -109,11 +109,24 @@ public class Column {
*/
public void setFormat(String value){
this.format = value;
if (this.dataType == DataType.DATE) {
this.dateTimeFormatter = DateTimeFormatter.ofPattern(value);
}
}
/**
* Get print format
* @return Print format string
*/
public String getPrintFormat() {
return this.printFormat;
}
/**
* Set print format
* @param value Print format string
*/
public void setPrintFormat(String value) {
this.printFormat = value;
}
/**
* Get format length
* @return Format length
@ -132,16 +145,22 @@ public class Column {
// </editor-fold>
// <editor-fold desc="Methods">
/**
* Factory method
* @param name Name
* @param dtype Data type
* @param dataType Data type
* @return Column
*/
public static Column factory(String name, DataType dtype){
return new Column(name, dtype);
public static Column factory(String name, DataType dataType) {
switch (dataType) {
case DATE:
return new DateTimeColumn(name);
default:
return new Column(name, dataType);
}
}
/**
* Factory method
* @param name Name
@ -162,7 +181,11 @@ public class Column {
return col;
}
}
return new Column(name, dtype);
Column column = new Column(name, dtype);
column.updateFormat(array);
return column;
}
/**
@ -170,10 +193,12 @@ public class Column {
*/
public void updateFormat(){
this.format = null;
this.printFormat = null;
switch (this.dataType){
case FLOAT:
case DOUBLE:
this.format = "%f";
this.format = "%f";
this.printFormat = "%f";
break;
}
this.formatLen = this.name.length();
@ -199,7 +224,7 @@ public class Column {
nn = str.length() - ci - 1;
if (nf < nn) {
nf = nn;
if (nf == 6)
if (nf >= 6)
break;
}
}
@ -207,18 +232,15 @@ public class Column {
ci = smax.indexOf(".");
int len = ci + nf + 2;
formatLen = Math.max(formatLen, len);
this.format = "%" + String.valueOf(formatLen) + "." + String.valueOf(nf) + "f";
this.format = "%f";
this.printFormat = "%" + String.valueOf(formatLen) + "." + String.valueOf(nf) + "f";
break;
case INT:
int imax = (int)ArrayMath.max(data);
smax = Integer.toString(imax);
formatLen = Math.max(formatLen, smax.length());
this.format = "%" + String.valueOf(formatLen) + "d";
break;
case DATE:
if (dateTimeFormatter == null) {
dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME;
}
this.format = "%d";
this.printFormat = "%" + String.valueOf(formatLen) + "d";
break;
default:
String v;
@ -230,7 +252,8 @@ public class Column {
if (formatLen < v.length())
formatLen = v.length();
}
this.format = "%" + String.valueOf(formatLen) + "s";
this.format = "%s";
this.printFormat = "%" + String.valueOf(formatLen) + "s";
break;
}
}
@ -268,13 +291,20 @@ public class Column {
if (format == null)
return o.toString();
else {
if (this.dataType == DataType.DATE) {
if (this.dateTimeFormatter == null) {
this.dateTimeFormatter = DateTimeFormatter.ofPattern(this.format);
}
return ((LocalDateTime) o).format(this.dateTimeFormatter);
} else
return String.format(Locale.US, format, o);
return String.format(Locale.US, format, o);
}
}
/**
* Print an object (same datatype with this column) to string
* @param o
* @return String
*/
public String print(Object o){
if (this.printFormat == null)
return o.toString();
else {
return String.format(Locale.US, this.printFormat, o);
}
}
@ -286,6 +316,7 @@ public class Column {
public Object clone() {
Column col = new Column(this.name, this.dataType);
col.setFormat(this.format);
col.setPrintFormat(this.printFormat);
col.setFormatLen(this.formatLen);
return col;
}

View File

@ -113,18 +113,34 @@ public class DataFrame implements Iterable {
if (columns.size() == 1) {
this.data = new ArrayList<>();
((List) this.data).add(data);
columns.get(0).updateFormat((Array) data);
} else {
if (((Array) data).getSize() == columns.size()) {
this.data = ((Array) data).reshape(new int[]{1, columns.size()});
this.array2D = true;
for (Column col : columns) {
col.updateFormat((Array) data);
}
}
}
} else { //Two dimension array
this.data = data;
this.array2D = true;
Column column = columns.get(0);
column.updateFormat((Array) data);
for (int i = 1; i < columns.size(); i++) {
Column col = columns.get(i);
col.setFormat(column.format);
col.setPrintFormat(column.printFormat);
col.setFormatLen(column.formatLen);
}
}
} else {
this.data = data;
int n = ((List) data).size();
for (int i = 0; i < n; i++) {
columns.get(i).updateFormat(((List<Array>) data).get(i));
}
}
this.columns = columns;
@ -141,7 +157,6 @@ public class DataFrame implements Iterable {
public DataFrame(Index index, List<String> columns, Object data) {
this.columns = new ColumnIndex();
if (data instanceof Array) {
List<DataType> dtypes = new ArrayList<>();
if (((Array) data).getRank() == 1) { //One dimension array
this.data = new ArrayList<>();
((List) this.data).add(data);
@ -162,9 +177,13 @@ public class DataFrame implements Iterable {
columns.add("C_" + String.valueOf(i));
}
}
for (int i = 0; i < n; i++) {
dtypes.add(((Array) data).getDataType());
this.columns.add(new Column(columns.get(i), dtypes.get(i)));
DataType dataType = ((Array) data).getDataType();
Column column = Column.factory(columns.get(0), (Array) data);
this.columns.add(column);
for (int i = 1; i < n; i++) {
Column col = (Column) column.clone();
col.setName(columns.get(i));
this.columns.add(col);
}
}
} else {
@ -177,7 +196,7 @@ public class DataFrame implements Iterable {
}
}
for (int i = 0; i < n; i++) {
this.columns.add(new Column(columns.get(i), ((List<Array>) data).get(i).getDataType()));
this.columns.add(Column.factory(columns.get(i), ((List<Array>) data).get(i)));
}
}
@ -2480,7 +2499,7 @@ public class DataFrame implements Iterable {
sb.append(this.index.toString(r));
for (int i = 0; i < this.size(); i++) {
sb.append(" ");
sb.append(this.columns.get(i).toString(this.getValue(r, i)));
sb.append(this.columns.get(i).print(this.getValue(r, i)));
}
sb.append("\n");
}
@ -2641,26 +2660,26 @@ public class DataFrame implements Iterable {
String colName = titleArray.get(idx).trim();
if (colFormat.equals("C") || colFormat.equals("s")) //String
{
col = new Column(colName, DataType.STRING);
col = Column.factory(colName, DataType.STRING);
} else if (colFormat.equals("i")) //Integer
{
col = new Column(colName, DataType.INT);
col = Column.factory(colName, DataType.INT);
} else if (colFormat.equals("f")) //Float
{
col = new Column(colName, DataType.FLOAT);
col = Column.factory(colName, DataType.FLOAT);
} else if (colFormat.equals("d")) //Double
{
col = new Column(colName, DataType.DOUBLE);
col = Column.factory(colName, DataType.DOUBLE);
} else if (colFormat.equals("B")) //Boolean
{
col = new Column(colName, DataType.BOOLEAN);
col = Column.factory(colName, DataType.BOOLEAN);
} else if (colFormat.substring(0, 1).equals("{")) { //Date
int eidx = colFormat.indexOf("}");
String formatStr = colFormat.substring(1, eidx);
col = new Column(colName, DataType.DATE);
col = Column.factory(colName, DataType.DATE);
col.setFormat(formatStr);
} else {
col = new Column(colName, DataType.STRING);
col = Column.factory(colName, DataType.STRING);
}
cols.add(col);
values.add(new ArrayList<>());
@ -2928,26 +2947,26 @@ public class DataFrame implements Iterable {
String colName = titleArray.get(idx).trim();
if (colFormat.equals("C") || colFormat.equals("s")) //String
{
col = new Column(colName, DataType.STRING);
col = Column.factory(colName, DataType.STRING);
} else if (colFormat.equals("i")) //Integer
{
col = new Column(colName, DataType.INT);
col = Column.factory(colName, DataType.INT);
} else if (colFormat.equals("f")) //Float
{
col = new Column(colName, DataType.FLOAT);
col = Column.factory(colName, DataType.FLOAT);
} else if (colFormat.equals("d")) //Double
{
col = new Column(colName, DataType.DOUBLE);
col = Column.factory(colName, DataType.DOUBLE);
} else if (colFormat.equals("B")) //Boolean
{
col = new Column(colName, DataType.BOOLEAN);
col = Column.factory(colName, DataType.BOOLEAN);
} else if (colFormat.substring(0, 1).equals("{")) { //Date
int eidx = colFormat.indexOf("}");
String formatStr = colFormat.substring(1, eidx);
col = new Column(colName, DataType.DATE);
col = Column.factory(colName, DataType.DATE);
col.setFormat(formatStr);
} else {
col = new Column(colName, DataType.STRING);
col = Column.factory(colName, DataType.STRING);
}
cols.add(col);
values.add(new ArrayList<>());
@ -3133,25 +3152,26 @@ public class DataFrame implements Iterable {
sw.write(str);
String line, vstr;
List<String> formats = new ArrayList<>();
List<Column> columns = new ArrayList<>();
if (formatSpec == null) {
for (Column col : this.columns) {
Column column = (Column) col.clone();
if (col.getDataType() == DataType.FLOAT || col.getDataType() == DataType.DOUBLE) {
formats.add(floatFormat == null ? col.getFormat() : floatFormat);
} else {
formats.add(col.getFormat());
column.setFormat(floatFormat == null ? col.getFormat() : floatFormat);
}
columns.add(column);
}
} else {
String[] formatStrs = formatSpec.split("%");
int i = 1;
for (Column col : this.columns) {
Column column = (Column) col.clone();
if (i < formatStrs.length) {
if (formatStrs[i].equals("i"))
formatStrs[i] = "d";
formats.add("%" + formatStrs[i]);
column.setFormat("%" + formatStrs[i]);
} else {
formats.add(col.getFormat());
column.setFormat(col.getFormat());
}
i += 1;
}
@ -3163,11 +3183,7 @@ public class DataFrame implements Iterable {
line = this.index.toString(j, idxFormat).trim();
}
for (int i = 0; i < this.size(); i++) {
if (formats.get(i) == null) {
vstr = this.getValue(j, i).toString();
} else {
vstr = String.format(Locale.US, formats.get(i), this.getValue(j, i));
}
vstr = columns.get(i).toString(this.getValue(j, i));
if (line.isEmpty()) {
line = vstr;
} else {

View File

@ -44,7 +44,7 @@ public class DateTimeColumn extends Column {
*/
public DateTimeColumn(String name, String format) {
this.name = name;
this.dataType = DataType.OBJECT;
this.dataType = DataType.DATE;
this.format = format;
this.formatLen = Math.max(this.name.length(), this.format.length());
this.dateTimeFormatter = DateTimeFormatter.ofPattern(this.format);
@ -62,11 +62,32 @@ public class DateTimeColumn extends Column {
this.formatLen = Math.max(this.name.length(), this.format.length());
}
/**
* Get DateTimeFormatter
* @return DataTimeFormatter
*/
public DateTimeFormatter getDateTimeFormatter() {
return this.dateTimeFormatter;
}
/**
* Set DateTimeFormatter
* @param value DateTimeFormatter
*/
public void setDateTimeFormatter(DateTimeFormatter value) {
this.dateTimeFormatter = value;
}
@Override
public String toString(Object o) {
return toString((LocalDateTime) o);
}
@Override
public String print(Object o) {
return toString((LocalDateTime) o);
}
/**
* Convert DateTime object to string
*
@ -113,4 +134,18 @@ public class DateTimeColumn extends Column {
}
this.setFormat(ff);
}
/**
*
* @return Column
*/
@Override
public Object clone() {
DateTimeColumn col = new DateTimeColumn(this.name);
col.setFormat(this.format);
col.setPrintFormat(this.printFormat);
col.setFormatLen(this.formatLen);
col.setDateTimeFormatter(this.dateTimeFormatter);
return col;
}
}

View File

@ -1,30 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\common_math\linalg">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\micaps"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart\text"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart\latex"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart\legend"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\geoshow"/>
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\maskout"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\topology"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\ascii"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\funny"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\linalg"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\funny"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\dataframe"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\matlab"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\micaps\mdfs_10.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\linalg\cross.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf\shitshape_ice_cream_cone.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf\shitshiape_bouquet.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\micaps\mdfs_10.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\linalg\cross.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf\shitshape_ice_cream_cone.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\surf\shitshiape_bouquet.py"/>
</RecentFiles>
</File>
<Font>

View File

@ -24,8 +24,10 @@ public class Mat {
MatFile mat = Mat5.newReader(source).readMat();
Map<String, Array> map = new HashMap<>();
for (MatFile.Entry entry : mat.getEntries()) {
Array array = MatLabUtil.fromMatLabArray((Matrix) entry.getValue());
map.put(entry.getName(), array);
if (entry.getValue() instanceof Matrix) {
Array array = MatLabUtil.fromMatLabArray((Matrix) entry.getValue());
map.put(entry.getName(), array);
}
}
return map;