Skip to content

Instantly share code, notes, and snippets.

@swarbhanu
Created November 29, 2011 14:56
Show Gist options
  • Save swarbhanu/1405074 to your computer and use it in GitHub Desktop.
Save swarbhanu/1405074 to your computer and use it in GitHub Desktop.
Example showing how to add a column in PyTables
from tables import *
# Describe a water class
class Water(IsDescription):
waterbody_name = StringCol(16, pos=1) # 16-character String
lati = Int32Col(pos=2) # integer
longi = Int32Col(pos=3) # integer
airpressure = Float32Col(pos=4) # float (single-precision)
temperature = Float64Col(pos=5) # double (double-precision)
# Open a file in "w"rite mode
fileh = openFile("myadd-column.h5", mode = "w")
# Create a new group
group = fileh.createGroup(fileh.root, "newgroup")
# Create a new table in newgroup group
table = fileh.createTable(group, 'table', Water, "A table", Filters(1))
# Append several rows
table.append([("Atlantic", 10, 0, 10*10, 10**2),
("Pacific", 11, -1, 11*11, 11**2),
("Atlantic", 12, -2, 12*12, 12**2)])
print "Contents of the original table:", fileh.root.newgroup.table[:]
# Create another table but this time in the root directory
tableroot = fileh.createTable(fileh.root, 'root_table', Water, "A table at root", Filters(1))
# Append data...
tableroot.append([("Mediterranean", 10, 0, 10*10, 10**2),
("Mediterranean", 11, -1, 11*11, 11**2),
("Adriatic", 12, -2, 12*12, 12**2)])
# close the file
# close the file
fileh.close()
# Open it again in append mode
fileh = openFile("myadd-column.h5", "a")
group = fileh.root.newgroup
table = group.table
# Get a description of table in dictionary format
descr = table.description._v_colObjects
descr2 = descr.copy()
# Add a column to description
descr2["hot"] = BoolCol(dflt=False)
# Create a new table with the new description
table2 = fileh.createTable(group, 'table2', descr2, "A table", Filters(1))
# Copy the user attributes
table.attrs._f_copy(table2)
# Fill the rows of new table with default values
for i in xrange(table.nrows):
table2.row.append()
# Flush the rows to disk
table2.flush()
# Copy the columns of source table to destination
for col in descr:
getattr(table2.cols, col)[:] = getattr(table.cols, col)[:]
# Fill the new column
table2.cols.hot[:] = [ row["temperature"] > 11**2 for row in table ]
# Remove the original table
table.remove()
# Move table2 to table
table2.move('/newgroup','table')
# Print the new table
print "Contents of the table with column added:", fileh.root.newgroup.table[:]
# Finally, close the file
fileh.close()
@CharlesB2
Copy link

@0todd0000
Copy link

Thank you for your scripts, very helpful!!

Based on your code I've created the add_column function below, which is independent of specific table descriptions. It's not thorough but seems to work for simple cases.

import tables

def add_column(table, ColClass, collabel, colvalues):

    #Step 1: Adjust table description 
    d           = table.description._v_colobjects.copy()  #original description
    d[collabel] = ColClass() #add column

    #Step 2: Create new temporary table:
    newtable    = tables.Table(table._v_file.root, '_temp_table', d, filters=table.filters)  # new table
    ###Step 2a: Copy attributes:
    table.attrs._f_copy(newtable)
    ###Step 2b: Copy table rows, also add new column values:
    for row,value in zip(table,colvalues):
    	newtable.append( [ tuple(list(row[:]) + [value]) ] )
    newtable.flush()

    #Step 3: Move temporary table to original location:
    parent      = table._v_parent  #original table location
    name        = table._v_name    #original table name
    table.remove()                 #remove original table
    newtable.move(parent, name)    #move temporary table to original location
    
    return newtable

Here is an example that uses add_column:

# Create HDF5 file, containing one table with two columns, four rows, and two attributes:

class MyTable(tables.IsDescription):
    name   = tables.StringCol(16, pos=0)
    x      = tables.FloatCol(pos=1)

fnameH5    = '/Users/username/Desktop/mydb.h5'

with tables.open_file(fnameH5, 'w') as fid:
    table  = fid.create_table(fid.root, 'mytable', MyTable)
    # add rows:
    table.append([('AAA', 1.5)])
    table.append([('BBB', 8.1)])
    table.append([('CCC', 18.7)])
    table.append([('DDD', 5.3)])
    # add attributes:
    table.set_attr('MyAttr0', 123)
    table.set_attr('MyAttr1', 'my message')

# Add column to the table:
with tables.open_file(fnameH5, 'r+') as fid:
    table     = fid.root.mytable  #table to which column is to be appended
    ColClass  = tables.UInt16Col  #new column class
    collabel  = 'y'               #new column label
    colvalues = [1, 3, 1, 2]      #new column values
    newtable  = add_column(table, ColClass, collabel, colvalues)
    print( fid.root.mytable[:] )  #"table" is gone and "newtable" is now fid.root.mytable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment