是否可以在磁盘上存储镶木地板文件,同时追加并按索引检索行?
Is it possible to store a parquet file on disk, while appending, and also retrieving rows by index?
我有185个数据文件,总共有3000万行。每两个都有两列;我想用作索引的单个整数和 512 个整数的列表。
所以看起来像这样
IndexID Ids
1899317 [0, 47715, 1757, 9, 38994, 230, 12, 241, 12228...
22861131 [0, 48156, 154, 6304, 43611, 11, 9496, 8982, 1...
2163410 [0, 26039, 41156, 227, 860, 3320, 6673, 260, 1...
15760716 [0, 40883, 4086, 11, 5, 18559, 1923, 1494, 4, ...
12244098 [0, 45651, 4128, 227, 5, 10397, 995, 731, 9, 3...
数据太大,无法加载到内存中,但我想使用索引列表一次检索几百行。
我从这条评论中得到了使用 Parquet 的建议。
Most efficient way of saving a pandas dataframe or 2d numpy array into h5py, with each row a seperate key, using a column
我一直在看官方镶木地板python指南
https://arrow.apache.org/docs/python/parquet.html
和
快速镶木地板指南
https://fastparquet.readthedocs.io/en/latest/api.html
但我似乎无法找到任何方法来使用索引检索行,如果 table 存储在磁盘上,或者是否全部加载到内存中。
这可能吗?如果是这样,我将如何做这样的事情?
例如
ParquetTable[22861131, 15760716]
[0, 48156, 154, 6304, 43611, 11, 9496, 8982, 1...
[0, 40883, 4086, 11, 5, 18559, 1923, 1494, 4, ...
Parquet 是一种列式数据存储,不适合您的用例。如果您的目标是存储太大而无法放入内存的数据,但仍然能够一次检索行进行处理,我建议您使用数据库。
最简单的数据库是 sqlite3
,它内置于 Python 本身。 Sqlite 数据库存储为文件,而不需要您设置数据库系统。
在我们继续之前,您需要将您的列表列分解为 512 列,以 (1) 使它们更易于使用,以及 (2) 我不认为数据库系统天生就支持列表.
这是一个关于如何转储数据和检索所需行的最小示例:
# Creating sample data to work on
import pandas as pd
import numpy as np
df = pd.DataFrame(
data=np.random.randint(low=1, high=1000, size=(1000, 3)),
columns=['a', 'b', 'c'],
index=pd.Series(range(1000), name='IndexID')
)
import sqlite3
# Write dataframes to database
with sqlite3.connect('sqlite.db') as conn:
df.to_sql('data', con=conn, if_exists='append')
上面的代码将 df
的内容转储到您当前工作目录中名为 sqlite.db
的 sqlite 数据库中。注意 to_sql
调用中的 if_exists
选项;如果要覆盖现有数据库,则需要将其更改为 replace
。
当您想从同一工作目录中检索特定行时,您可以运行以下操作。下面的示例检索第 200 到第 210 个索引:
# How to read from database
with sqlite3.connect('sqlite.db') as conn:
# `rowid` is a keyword in sqlite queries to represent the index
query = "SELECT * FROM data WHERE rowid BETWEEN %d AND %d" % (200, 210)
subset = pd.read_sql(query, con=conn)
print(subset)
# This prints the following
# IndexID a b c
# 0 199 704 3 423
# 1 200 590 299 767
# 2 201 45 953 560
# 3 202 237 662 746
# 4 203 123 920 275
# 5 204 453 10 370
# 6 205 35 628 602
# 7 206 957 465 735
# 8 207 602 810 154
# 9 208 927 796 352
# 10 209 969 130 217
有关在 sqlite3 和 pandas 之间移动数据的更多信息,我建议阅读这篇 https://www.dataquest.io/blog/python-pandas-databases/ and 。
我有185个数据文件,总共有3000万行。每两个都有两列;我想用作索引的单个整数和 512 个整数的列表。
所以看起来像这样
IndexID Ids
1899317 [0, 47715, 1757, 9, 38994, 230, 12, 241, 12228...
22861131 [0, 48156, 154, 6304, 43611, 11, 9496, 8982, 1...
2163410 [0, 26039, 41156, 227, 860, 3320, 6673, 260, 1...
15760716 [0, 40883, 4086, 11, 5, 18559, 1923, 1494, 4, ...
12244098 [0, 45651, 4128, 227, 5, 10397, 995, 731, 9, 3...
数据太大,无法加载到内存中,但我想使用索引列表一次检索几百行。
我从这条评论中得到了使用 Parquet 的建议。 Most efficient way of saving a pandas dataframe or 2d numpy array into h5py, with each row a seperate key, using a column
我一直在看官方镶木地板python指南
https://arrow.apache.org/docs/python/parquet.html
和
快速镶木地板指南
https://fastparquet.readthedocs.io/en/latest/api.html
但我似乎无法找到任何方法来使用索引检索行,如果 table 存储在磁盘上,或者是否全部加载到内存中。
这可能吗?如果是这样,我将如何做这样的事情?
例如
ParquetTable[22861131, 15760716]
[0, 48156, 154, 6304, 43611, 11, 9496, 8982, 1... [0, 40883, 4086, 11, 5, 18559, 1923, 1494, 4, ...
Parquet 是一种列式数据存储,不适合您的用例。如果您的目标是存储太大而无法放入内存的数据,但仍然能够一次检索行进行处理,我建议您使用数据库。
最简单的数据库是 sqlite3
,它内置于 Python 本身。 Sqlite 数据库存储为文件,而不需要您设置数据库系统。
在我们继续之前,您需要将您的列表列分解为 512 列,以 (1) 使它们更易于使用,以及 (2) 我不认为数据库系统天生就支持列表.
这是一个关于如何转储数据和检索所需行的最小示例:
# Creating sample data to work on
import pandas as pd
import numpy as np
df = pd.DataFrame(
data=np.random.randint(low=1, high=1000, size=(1000, 3)),
columns=['a', 'b', 'c'],
index=pd.Series(range(1000), name='IndexID')
)
import sqlite3
# Write dataframes to database
with sqlite3.connect('sqlite.db') as conn:
df.to_sql('data', con=conn, if_exists='append')
上面的代码将 df
的内容转储到您当前工作目录中名为 sqlite.db
的 sqlite 数据库中。注意 to_sql
调用中的 if_exists
选项;如果要覆盖现有数据库,则需要将其更改为 replace
。
当您想从同一工作目录中检索特定行时,您可以运行以下操作。下面的示例检索第 200 到第 210 个索引:
# How to read from database
with sqlite3.connect('sqlite.db') as conn:
# `rowid` is a keyword in sqlite queries to represent the index
query = "SELECT * FROM data WHERE rowid BETWEEN %d AND %d" % (200, 210)
subset = pd.read_sql(query, con=conn)
print(subset)
# This prints the following
# IndexID a b c
# 0 199 704 3 423
# 1 200 590 299 767
# 2 201 45 953 560
# 3 202 237 662 746
# 4 203 123 920 275
# 5 204 453 10 370
# 6 205 35 628 602
# 7 206 957 465 735
# 8 207 602 810 154
# 9 208 927 796 352
# 10 209 969 130 217
有关在 sqlite3 和 pandas 之间移动数据的更多信息,我建议阅读这篇 https://www.dataquest.io/blog/python-pandas-databases/ and