0

我有一个 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})

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

谢谢。

4

2 回答 2

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

追加行

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)
于 2015-02-24T02:50:59.337 回答
0

您正在分配一个objectdtype、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
于 2015-02-24T11:11:04.797 回答