Python 在PyTables中添加列以创建新表并进行复制的唯一方法是什么?

Python 在PyTables中添加列以创建新表并进行复制的唯一方法是什么?,python,pytables,Python,Pytables,我正在寻找一种能够处理存储在磁盘上的异构数据的持久数据存储解决方案。PyTables似乎是一个明显的选择,但我能找到的关于如何附加新列的唯一信息是一个教程示例。本教程让用户创建一个新表,添加列,将旧表复制到新表中,最后删除旧表。这似乎是一个巨大的痛苦。必须这样做吗 如果是这样的话,在磁盘上存储混合数据时,有哪些更好的选择可以相对轻松地容纳新列?我也看过sqlite3,其中的列选项似乎也相当有限。是的,您必须创建一个新表并复制原始数据。这是因为表是一种密集格式。这给它带来了巨大的性能优势,但其中一

我正在寻找一种能够处理存储在磁盘上的异构数据的持久数据存储解决方案。PyTables似乎是一个明显的选择,但我能找到的关于如何附加新列的唯一信息是一个教程示例。本教程让用户创建一个新表,添加列,将旧表复制到新表中,最后删除旧表。这似乎是一个巨大的痛苦。必须这样做吗


如果是这样的话,在磁盘上存储混合数据时,有哪些更好的选择可以相对轻松地容纳新列?我也看过sqlite3,其中的列选项似乎也相当有限。

是的,您必须创建一个新表并复制原始数据。这是因为表是一种密集格式。这给它带来了巨大的性能优势,但其中一个成本是添加新列有点昂贵

谢谢你的回答

我搜索了这个网站,在github中,我发现有人展示了如何在Pytable中添加列。 显示如何在PyTables中添加列的示例

,示例显示了如何在PyTables中添加列,但迁移起来有些困难

,隔离了复制逻辑,但有些术语已弃用,并且在添加新列时出现了一些小错误

根据他们的贡献,我更新了在PyTables中添加新列的代码。(Python 3.6,windows)


你试过mongo吗?我已经试过了,但是熊猫使用的许多numpy数据类型在本地并不兼容。我找不到一种方法可以像使用sqlite3那样使用mongo注册新的数据类型。你运气好吗?我目前采用的方法是使用HDFStore并将每个数据帧列放在自己的节点中。查看此问题:看起来这可能值得关注:感谢分享。事实上,我意识到我在数据库方面的糟糕背景阻碍了我在这个问题上的持续发展。有关最新版本,请参阅
# -*- coding: utf-8 -*-
"""
PyTables, append a column
    """
import tables as tb
pth='d:/download/'

# Describe a water class
class Water(tb.IsDescription):
    waterbody_name   = tb.StringCol(16, pos=1)   # 16-character String
    lati             = tb.Int32Col(pos=2)        # integer
    longi            = tb.Int32Col(pos=3)        # integer
    airpressure      = tb.Float32Col(pos=4)      # float  (single-precision)
    temperature      = tb.Float64Col(pos=5)      # double (double-precision)

# Open a file in "w"rite mode
# if don't include pth, then it will be in the same path as the code.
fileh = tb.open_file(pth+"myadd-column.h5", mode = "w")

# Create a table in the root directory and append data...
tableroot = fileh.create_table(fileh.root, 'root_table', Water,
                               "A table at root", tb.Filters(1))
tableroot.append([("Mediterranean", 10, 0, 10*10, 10**2),
              ("Mediterranean", 11, -1, 11*11, 11**2),
              ("Adriatic", 12, -2, 12*12, 12**2)])
print ("\nContents of the table in root:\n",
       fileh.root.root_table[:])

# Create a new table in newgroup group and append several rows
group = fileh.create_group(fileh.root, "newgroup")
table = fileh.create_table(group, 'orginal_table', Water, "A table", tb.Filters(1))
table.append([("Atlantic", 10, 0, 10*10, 10**2),
              ("Pacific", 11, -1, 11*11, 11**2),
              ("Atlantic", 12, -2, 12*12, 12**2)])
print ("\nContents of the original table in newgroup:\n",
       fileh.root.newgroup.orginal_table[:])
# close the file
fileh.close()

#%% Open it again in append mode
fileh = tb.open_file(pth+"myadd-column.h5", "a")
group = fileh.root.newgroup
table = group.orginal_table

# Isolated the copying logic
def append_column(table, group, name, column):
    """Returns a copy of `table` with an empty `column` appended named `name`."""
    description = table.description._v_colObjects.copy()
    description[name] = column
    copy = tb.Table(group, table.name+"_copy", description)

    # Copy the user attributes
    table.attrs._f_copy(copy)

    # Fill the rows of new table with default values
    for i in range(table.nrows):
        copy.row.append()
    # Flush the rows to disk
    copy.flush()

    # Copy the columns of source table to destination
    for col in descr:
        getattr(copy.cols, col)[:] = getattr(table.cols, col)[:]

    # choose wether remove the original table
#    table.remove()

    return copy

# Get a description of table in dictionary format
descr = table.description._v_colObjects
descr2 = descr.copy()

# Add a column to description
descr2["hot"] = tb.BoolCol(dflt=False)

# append orginal and added data to table2 
table2 = append_column(table, group, "hot", tb.BoolCol(dflt=False))
# Fill the new column
table2.cols.hot[:] = [row["temperature"] > 11**2 for row in table ]
# Move table2 to table, you can use the same name as original one.
table2.move('/newgroup','new_table')

# Print the new table
print ("\nContents of the table with column added:\n",
       fileh.root.newgroup.new_table[:])
# Finally, close the file
fileh.close()