我有一个RAM使用问题-我从DB获取相当多的数据,并将其倒入pandas DataFrame中,在那里我做groub_by
列表- DB不是很擅长。
问题是,当我获取大约40列时,pandas并不能很好地确定每个列的dtype。我希望为每个列分别指定dtype,这样pandas使用object
dtype时就不会到处使用那么多内存。我知道,我可以转换数据帧之后,但这并不能解决内存超限。
import pandas as pd
import numpy as np
# Just a sample sql
sql = "select premise_id, parent_id, addr_ward FROM table;"
# This is list of tuples from database
rows = safe_call_db_read(db.conn, sql)
logger.info("Db fetched dataframe")
dtype = {
'premise_id': np.int64,
'parent_id': np.int64,
'addr_ward': object
}
data_frame = pd.DataFrame(data=rows, dtype=dtype)
这失败了,因为只允许一个dtype作为参数,抛出
TypeError: object of type 'type' has no len()
这糟透了。
是否有一些方法在实际加载数据之前为每个列声明dtypes,这将以最佳方式保存每个列,从而节省我一些RAM?
也许创建空数据框架,为每列声明dtype,然后追加行?
您可能想尝试pandas方法read_sql_query直接将SQL查询读取到数据框中,您可以将创建的dtype字典作为dtype参数。
您只需要事先通过sqlite3(例如)创建一个到数据库的连接。
我会尝试pandas.from_records,它有一个coerce_float
选项,并说它对SQL结果集很有用。正如@maxxel_所指出的,从SQL数据库中读取数据是最简单的,因为Pandas可以使用SQL定义来获取数据类型,但是从您的代码中,您似乎有一个具有额外处理/等的子例程。
下面是从文档中复制的一个示例,它显示了为每个列独立定义的dtype
:
>>> data = np.array([(3, 'a'), (2, 'b'), (1, 'c'), (0, 'd')],
... dtype=[('col_1', 'i4'), ('col_2', 'U1')])
>>> pd.DataFrame.from_records(data)
col_1 col_2
0 3 a
1 2 b
2 1 c
3 0 d