【问题标题】:Pandas dataframe and speed熊猫数据框和速度
【发布时间】:2015-04-25 10:51:21
【问题描述】:

我有一个 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 之类的东西来提高写入速度,同时保持高读取速度吗?

谢谢。

【问题讨论】:

    标签: python pandas hdfstore


    【解决方案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)
    

    【讨论】:

      【解决方案2】:

      您分配的系列是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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-09
        相关资源
        最近更新 更多