polishing

columns is the term used py pandas
This commit is contained in:
Martin Diehl 2019-11-28 05:52:23 +01:00
parent a8016d64bb
commit ca92400c2f
1 changed files with 62 additions and 22 deletions

View File

@ -6,7 +6,7 @@ import numpy as np
class Table(): class Table():
"""Store spreadsheet-like data.""" """Store spreadsheet-like data."""
def __init__(self,array,headings,comments=None): def __init__(self,array,columns,comments=None):
""" """
New spreadsheet data. New spreadsheet data.
@ -14,8 +14,8 @@ class Table():
---------- ----------
array : numpy.ndarray array : numpy.ndarray
Data. Data.
headings : dict columns : dict
Column headings. Labels as keys and shape as tuple. Example 'F':(3,3) for a deformation gradient. Column labels and shape. Example 'F':(3,3) for a deformation gradient.
comments : iterable of str, optional comments : iterable of str, optional
Additional, human-readable information Additional, human-readable information
@ -24,8 +24,8 @@ class Table():
d = {} d = {}
i = 0 i = 0
for label in headings: for label in columns:
for components in range(np.prod(headings[label])): for components in range(np.prod(columns[label])):
d[i] = label d[i] = label
i+=1 i+=1
@ -36,7 +36,7 @@ class Table():
else: else:
self.comments = [c for c in comments] self.comments = [c for c in comments]
self.headings = headings self.columns = columns
@staticmethod @staticmethod
def from_ASCII(fname): def from_ASCII(fname):
@ -46,6 +46,12 @@ class Table():
The first line needs to indicate the number of subsequent header lines as 'n header'. The first line needs to indicate the number of subsequent header lines as 'n header'.
Vector data labels are indicated by '1_x, 2_x, ..., n_x'. Vector data labels are indicated by '1_x, 2_x, ..., n_x'.
Tensor data labels are indicated by '3x3:1_x, 3x3:2_x, ..., 3x3:9_x'. Tensor data labels are indicated by '3x3:1_x, 3x3:2_x, ..., 3x3:9_x'.
Parameters
----------
fname : file, str, or pathlib.Path
Filename or file for reading.
""" """
try: try:
f = open(fname) f = open(fname)
@ -60,20 +66,20 @@ class Table():
comments = [f.readline()[:-1] for i in range(header-1)] comments = [f.readline()[:-1] for i in range(header-1)]
labels = f.readline().split() labels = f.readline().split()
headings = {} columns = {}
for label in labels: for label in labels:
tensor_column = re.search(r'[0-9,x]*?:[0-9]*?_',label) tensor_column = re.search(r'[0-9,x]*?:[0-9]*?_',label)
if tensor_column: if tensor_column:
my_shape = tensor_column.group().split(':',1)[0].split('x') my_shape = tensor_column.group().split(':',1)[0].split('x')
headings[label.split('_',1)[1]] = tuple([int(d) for d in my_shape]) columns[label.split('_',1)[1]] = tuple([int(d) for d in my_shape])
else: else:
vector_column = re.match(r'[0-9]*?_',label) vector_column = re.match(r'[0-9]*?_',label)
if vector_column: if vector_column:
headings[label.split('_',1)[1]] = (int(label.split('_',1)[0]),) columns[label.split('_',1)[1]] = (int(label.split('_',1)[0]),)
else: else:
headings[label]=(1,) columns[label]=(1,)
return Table(np.loadtxt(f),headings,comments) return Table(np.loadtxt(f),columns,comments)
def get_array(self,label): def get_array(self,label):
"""Return data as array.""" """Return data as array."""
@ -81,10 +87,22 @@ class Table():
idx,key = label.split('_',1) idx,key = label.split('_',1)
return self.data[key].to_numpy()[:,int(idx)-1] return self.data[key].to_numpy()[:,int(idx)-1]
else: else:
return self.data[label].to_numpy().reshape((-1,)+self.headings[label]) return self.data[label].to_numpy().reshape((-1,)+self.columns[label])
def set_array(self,label,array,info): def set_array(self,label,array,info):
"""Set data.""" """
Modify data in the spreadsheet.
Parameters
----------
label : str
Label for the new data
array : np.ndarray
New data
info : str
Human-readable information about the new data
"""
if np.prod(array.shape[1:],dtype=int) == 1: if np.prod(array.shape[1:],dtype=int) == 1:
self.comments.append('{}: {}'.format(label,info)) self.comments.append('{}: {}'.format(label,info))
else: else:
@ -97,34 +115,56 @@ class Table():
else: else:
self.data[label] = array.reshape(self.data[label].shape) self.data[label] = array.reshape(self.data[label].shape)
def get_labels(self): def get_labels(self):
"""Return the labels of all columns.""" """Return the labels of all columns."""
return [label for label in self.headings] return [label for label in self.columns]
def add_array(self,label,array,info): def add_array(self,label,array,info):
"""
Add data to the spreadsheet.
Parameters
----------
label : str
Label for the new data
array : np.ndarray
New data
info : str
Human-readable information about the new data
"""
if np.prod(array.shape[1:],dtype=int) == 1: if np.prod(array.shape[1:],dtype=int) == 1:
self.comments.append('{}: {}'.format(label,info)) self.comments.append('{}: {}'.format(label,info))
else: else:
self.comments.append('{} {}: {}'.format(label,array.shape[1:],info)) self.comments.append('{} {}: {}'.format(label,array.shape[1:],info))
self.headings[label] = array.shape[1:] if len(array.shape) > 1 else (1,) self.columns[label] = array.shape[1:] if len(array.shape) > 1 else (1,)
size = np.prod(array.shape[1:],dtype=int) size = np.prod(array.shape[1:],dtype=int)
new_data = pd.DataFrame(data=array.reshape(-1,size), new_data = pd.DataFrame(data=array.reshape(-1,size),
columns=[label for l in range(size)]) columns=[label for l in range(size)])
self.data = pd.concat([self.data,new_data],axis=1) self.data = pd.concat([self.data,new_data],axis=1)
def to_ASCII(self,fname): def to_ASCII(self,fname):
"""
Store as plain text file.
Parameters
----------
fname : file, str, or pathlib.Path
Filename or file for reading.
"""
labels = [] labels = []
for l in self.headings: for l in self.columns:
if(self.headings[l] == (1,)): if(self.columns[l] == (1,)):
labels.append('{}'.format(l)) labels.append('{}'.format(l))
elif(len(self.headings[l]) == 1): elif(len(self.columns[l]) == 1):
labels+=['{}_{}'.format(i+1,l)\ labels+=['{}_{}'.format(i+1,l)\
for i in range(self.headings[l][0])] for i in range(self.columns[l][0])]
else: else:
labels+=['{}:{}_{}'.format(i+1,'x'.join([str(d) for d in self.headings[l]]),l)\ labels+=['{}:{}_{}'.format(i+1,'x'.join([str(d) for d in self.columns[l]]),l)\
for i in range(np.prod(self.headings[l],dtype=int))] for i in range(np.prod(self.columns[l],dtype=int))]
header = ['{} header'.format(len(self.comments)+1)]\ header = ['{} header'.format(len(self.comments)+1)]\
+ self.comments\ + self.comments\