Pandas 数据帧和速度

Pandas dataframe and speed

我有一个 pandas 数据框对象,我已经预先分配了 400 000 个条目。 2 列 datetime.datetime 类型的时间戳和浮点数。 当我尝试在 table 中插入(覆盖)一行时,它看起来相当慢,具体取决于 table 的大小,我得到大约 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 之类的东西来提高写入速度,同时保持高读取速度吗?

谢谢。

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

那么,为什么不预先使用索引的关系型 SQL 引擎数据库构建数据集(追加行、更新记录、select 列),然后导入到 Python用于 analytical/graphical 目的的数据帧?示例包括:

数据库连接

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 EXPORT/IMPORT

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)

您正在分配一个 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

你可以绕过其中的大部分内容,但要逐项分配。这相当快,但你必须确保你的数据类型兼容。

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