熊猫数据帧和速度

时间:2015-02-23 23:00:01

标签: python pandas hdfstore

我有一个pandas数据帧对象,我预先分配了400,000个条目。 2列是datetime.datetime类型的时间戳和浮点数。 当我尝试在表中插入(覆盖)一行时,它似乎相当慢,这取决于表的大小,我得到0.044秒。 我创建了一个整数索引,我正在使用此索引来访问该行。 这是我如何使用它:

maxsize = 400000
data = pd.DataFrame({'ts' : date_list, 'val' : zeros}, index=range(maxsize))
# later on, the next statement is "slow"
data.iloc[0] = pd.Series({'ts' : datetime.datetime.now(), 'val': val})

根据我的调查,我的机器上的最后一个语句大约需要0.044秒(i7-4650U)。 这似乎很慢。我做的事情根本就是错误吗? 我可以使用像HDF Store这样的东西来提高写入速度,同时保持高读取速度吗?

感谢。

2 个答案:

答案 0 :(得分:1)

我认为您的解决方案不仅仅是编程解决方案。为什么使用Python作为数据存储处理程序,因为您担心性能?从本质上讲,Python类似于与从外部源提取的数据交互的客户端,即MySQL或SQLite等专用数据库(使用ODBC / OLEDB)。

那么,为什么不事先使用索引的关系型SQL引擎数据库构建数据集(追加行,更新记录,选择列),然后导入到Python数据框中以用于分析/图形目的?例子包括:

数据库连接

conn = sqlite3.connect("databasename.sqlite")
df = pd.read_sql("SELECT [field1], [field2] from datatable", conn)
df

APPEND ROWS

conn = sqlite3.connect('databasename.sqlite')
cur = conn.cursor()
sql =  "INSERT INTO datatable (field1, field2, field3) VALUES ('{0}','{1}','{2}');".format(items[0], items[1], items[2])

cur.execute(sql)
db.commit()

CSV导出/导入

conn = sqlite3.connect('databasename.sqlite')
cur = conn.cursor()
cur.execute("SELECT [field1], [field2] from datatable")

a = csv.writer(open('datafile.csv', 'w', newline=''))
for row in cur.fetchall() :
    a.writerow(row)

filepath = 'datafile.csv'  # OUTPUTTED PRIOR FROM DATABASE
tp = pd.io.parsers.read_csv(filepath, sep=',', iterator=True, chunksize=1000, encoding = "ISO-8859-1")
finaldf = pd.concat(list(tp), ignore_index=True)

答案 1 :(得分:0)

你正在分配一个object dtype,iow,它的混合系列。因此,当元素分配发生时,需要转换日期时间。所有这一切都很便宜;什么是昂贵的是每个列需要内部复制以防止dtype更改。在处理大量边缘情况的任务中,它们是相当多的验证。

In [23]: data = pd.DataFrame({'ts' : pd.date_range('20130101',freq='s',periods=maxsize), 'val' : 0}, index=range(maxsize))

In [24]: s = Series({'ts' : datetime.datetime.now(), 'val' : 1 })

In [25]: %timeit data.iloc[-1] = s
100 loops, best of 3: 10.6 ms per loop

你可以绕过很多这个,但是逐个项目分配。这非常快,但您必须确保您的dtypes兼容。

In [26]: def f():
    data.iat[-1,0] = s['ts']
    data.iat[-1,1] = s['val']
   ....:     

In [27]: data.tail()              
Out[27]: 
                               ts  val
399995        2013-01-05 15:06:35    0
399996        2013-01-05 15:06:36    0
399997        2013-01-05 15:06:37    0
399998        2013-01-05 15:06:38    0
399999 2015-02-24 06:03:58.344166    1

In [28]: %timeit f()
10000 loops, best of 3: 35.2 us per loop