2015-02-23 70 views
0

我有一个熊猫数据框对象,我预先分配了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商店的东西来提高写入速度,但也保持较高的读取速度吗?

谢谢。

回答

0

您分配了一系列为object D型,督察,其混合。所以当元素分配发生时,日期时间需要转换。所有这些都很便宜;什么是昂贵的是,每列需要内部复制,以防止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 
+0

iat的工作速度更快 – ren 2015-02-24 20:05:26

1

我认为你的解决方案更多的是一个过程而不是编程。为什么使用Python作为数据存储处理程序,因为担心性能?从本质上讲,Python将类似于与从外部源提取的数据(即专用数据库,如MySQL或SQLite(使用ODBC/OLEDB))交互的客户端。因此,为什么不事先使用索引的关系型SQL引擎数据库构造数据集(追加行,更新记录,选择列),然后导入到Python数据框中以用于分析/图形目的?为什么不使用索引的关系型SQL引擎数据库来构造数据集?例子包括:

数据库连接

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)