Issue 1:
Good afternoon. When dealing with scientific data, it would be very advantageous to add units of measure to columns such that a secondary column name represents the unit. Here is a use case scenario:

User imports navigation data from CSV where altitudes may be in meters, latitude/longitude in radians, and heading is in semi-circle. The unit data is in the second row of the file.

When importing into a dataframe, the user would specify units=2 for row two.

When the user wants to output units to a desired type, it as simple as:

df[['latitude','longitude']].units('degrees')

For any data that does not have a unit assigned or wants to convert the stored data to that type, the user can do:

df['North_Accel'].units(set='m/s^2').

This of course leads you to the method of converting units. It would be a series of files by measurement type (distance, volume, speed, force, pressure, temperature, data, etc) and in the files would be a table where the rows and columns equal all available units and the fields would contain the factor. Such that if you look up radians in the row and move across to degrees in the column, the entry would be 180/math.pi (preferred) or just 57.295779513.

You could potentially have fun with this when you have a timeseries index or a column with time assuming that you can create new units of measure based on the symbolic math. An example would be that you have distance in feet already and time in minutes and it would calculate out to 'ft/min'. df['velocity'] = df['distance'].diff()/df['time'].diff()

Since that extra feature is not likely to happen, you would have to tack on the unit types manually to ensure you get what you need.

df['velocity'] = (df['distance'].diff()/df['time'].diff()).units('ft/min')

However to ensure your imported data can stay be flexable, your script may need to take precautions by ensuring the output is the desired type

df['velocity'] = (df['distance'].units('ft').diff()/df['time'].units('min').diff()).units('ft/min')

That would ensure your source data can be any unit of distance, but would be converted to 'ft' first before dividing by time in minutes. Then you can send that series data in 'ft/min' to 'velocity' where it is stored as and set as 'ft/min'.

Thanks!

V/R,

Frank

Issue 2:
quantities related

xref #2494

xref #1071

custom meta-data

xref #2485

It would be very convenient if unit support could be integrated into pandas.

Idea: pandas checks for the presence of a unit-attribute of columns and - if present - uses it

with 'print' to show the units e.g. below the column names

to calculate 'under the hood' with these units similar to the example below

For my example I use the module pint and add an attribute 'unit' to columns (and a 'title'...).

Example:

from pandas import DataFrame as DF
from pint import UnitRegistry
units = UnitRegistry()

class ColumnDescription():
'''Column description with additional attributes.

The idea is to use this description to be able to add unit and title
attributes to a column description in one step.

A list of ColumnDescriptions is than used as argument to DataFrame()
with unit support.
'''

def __init__(self, name, data, title = None, unit = None):
'''
Args:
name (str): Name of the column..
data (list): List of the column data.
title (str): Title of the column. Defaults to None.
unit (str): Unit of the column (see documentation of module pint).
Defaults to None.

'''

self.data = data
'''(list): List of the column data.'''

self.name = name
'''(str): Name of the column, naming convention similar to python variables.

Used to access the column with pandas syntax, e.g. df['column'] or df.column.
'''

self.title = title
'''(str): Title of the column.

More human readable than the 'name'. E.g.:
Title: 'This is a column title'.
name: 'column_title'.
'''

self.unit = unit
'''Unit of the column (see module pint).

Intended to be used in calculations involving different columns.
'''

class DataFrame(DF):
'''Data Frame with support for ColumnDescriptions (e.g. unit support).

1. See documentation of pandas.DataFrame.
2. When used with ColumnDescriptions supports additional column attributes
like title and unit.
'''

def __init__(self, data, title = None):
'''
Args:
data (list or dict):
1. Dict, as in documentation of DataFrame
2. List of the column data (of type ColumnDescription).
title (str): Title of the data frame. Defaults to None.
'''

if isinstance(data, list):
if isinstance(data[0], ColumnDescription):
d = {}

for column in data:
d[column.name] = column.data

super(DataFrame, self).__init__(d)

for column in data:
self[column.name].title = column.title
self[column.name].unit = column.unit

self.title = title

else:
super(DataFrame, self).__init__(data)

if __name__ == '__main__':

data = [ ColumnDescription('length',
[1, 10],
title = 'Length in meter',
unit = 'meter'),
ColumnDescription('time',
[10, 1],
title = 'Time in s',
unit = 's') ]

d = {'length':[1, 10],
'time': [10, 1]}
df = DataFrame(d)
print 'standard df'
print df

df = DataFrame(data)
print '\n' + 'new df'
print df

####use of dimensions####
# pint works with numpy arrays
# df[name] is currently not working with pint, but would be I think
# it would be a real enhancement if it would...
test = df.as_matrix(['length']) * units(df['length'].unit) / \
(df.as_matrix(['time']) * units(df['time'].unit))
print '\n' + 'unit test'
print test
print '\n' + 'magnitude'
print test.magnitude
print '\n' + 'dimensionality'
print test.dimensionality