【问题标题】:pandas, chained indexing, spaces in csv, and speedpandas、链式索引、csv 中的空格和速度
【发布时间】:2015-06-02 18:45:30
【问题描述】:

我的问题是关于在 Python 2.7.9 中使用 Pandas 模块进行索引的速度。我正在使用 Pandas 0.12.0,因为 0.12.0 以上的所有版本都会使链接索引变慢,因为我使用的数据框缺少列值(即使链接索引警告关闭)。这是我的csv ('TESTDF.csv') 的链接

python 输入:

import pandas as pd
import numpy as np
import time

#importing raw data
Rawdf = pd.read_csv('TESTDF.csv')

# chained 1
t = time.time()
Rawdf['MONTH']=None
for i in range(0,1000):
    Rawdf['MONTH'][i] = int(Rawdf['DATE'][i][0:2].replace('/',''))
elapsed = time.time() - t  
print elapsed  

# unchained 1
t = time.time()
Rawdf['MONTH'] = None
for i in range(0,1000):
    Rawdf.loc[i,'MONTH'] = int(Rawdf.loc[i,'DATE'][0:2].replace('/',''))
elapsed = time.time() - t  
print elapsed

# unchained 2
t = time.time()
Rawdf['MONTH'] = None
#ADD MONTH, DAY, YEAR, and HOUR columns
for i in range(0,1000):
    Rawdf.loc[i,'MONTH'] = int(Rawdf.loc[i,'DATE'][0:2].replace('/',''))
elapsed = time.time() - t  
print elapsed  

# chained 2
t = time.time()
Rawdf['MONTH']=None
#ADD MONTH, DAY, YEAR, and HOUR columns
for i in range(0,1000):
    Rawdf['MONTH'][i] = int(Rawdf['DATE'][i][0:2].replace('/',''))
elapsed = time.time() - t  
print elapsed  

这是我的 python 输出:

0.0684299468994
9.38544201851
8.49306797981
0.0324759483337

如您所见,chained 的速度要快得多。为什么会有这样的速度差异?我很确定这与 csv 中缺少列值有关,想象它会产生如此大的差异是很有趣的。

【问题讨论】:

  • 我无法运行您的代码,如果您将顺序如此链式索引首先翻转然后正确的最后一个,会发生什么情况?通常,计时操作必须计算多次,并取最快时间的平均值以排除任何缓存
  • 请在您的问题中编辑代码更新,因为格式在 cmets 中丢失,我刚刚运行该代码并得到 chained indexing processing time: 2.3311331272125244 non-chained indexing processing time: 2.579148054122925 然后我翻转订单并得到:non-chained indexing processing time: 2.503142833709717 chained indexing processing time: 4.8432769775390625 所以我没有看到和你一样大的不同,订单很重要
  • 编辑您的问题并添加完整代码并删除您的评论
  • @EdChum 可能使用的是版本 15 或 16,而且很可能loc 自版本 12 以来性能有所改进。如果您有兴趣,可以查看发行说明。我的结果(15.2 版)肯定比你的更接近 Ed。
  • 感觉这里有一个XY problem——与其试图找出过时版本的熊猫的行为方式,不如描述你的实际问题可能会更有成效(“这就是我所拥有的,这就是我想要的,这是我到目前为止所做的,但是它太慢了——有没有更好的方法?”)。例如,如果您只想将月、日、年和小时提取到列中,我敢打赌,我们可以在 modern pandas 中击败您的最佳时间。

标签: python-2.7 indexing pandas


【解决方案1】:

(来自 pandas v15.2 的结果,完全使用 Eric 上面的代码(除了使用 nrows=1000 和 read_csv(),因为其余代码仅使用前 1,000 行。如果这很重要,那么我认为代码应该更改为使用超过前 1,000 行,因为在没有真正原因的情况下读取大 csv 有点痛苦。此外,您基本上可以使用 date_range 重新创建 csv。

25.5060670376   # chained 1
1.0301091671    # unchained 1
1.3660838604    # unchained 2
26.4075160027   # chainedd 2

(注意:此处的代码基于该问题的先前版本,因为已被删除,但我相信这些要点仍然有效,所以我将其留在这里)

扩展@EdChum 的优点...在 ipython 中执行此操作要容易得多,两种方法之间的区别更接近(而且您不必担心这种排序方式):

In [11]: pd.__version__
Out[11]: '0.15.2'

%timeit for i in range(0,6000,3): df.loc[i,'test']=666
1 loops, best of 3: 578 ms per loop

%timeit for i in range(0,6000,3): df['test'][i]=666
1 loops, best of 3: 220 ms per loop

我不想将“测试”重置为无,但这对时间来说真的不重要(因为你只是反复覆盖)。而且,我不知道您最终要测量什么,但是如果您对上述代码进行矢量化(您希望在实际应用程序中这样做),这两种方法的速度基本相同(更不用说大约 1000x比非矢量化版本更快):

%timeit df.ix[0:6000:3,'test']=666
1000 loops, best of 3: 348 µs per loop

%timeit df['test'][0:6000:3]=666
1000 loops, best of 3: 352 µs per loop

顺便说一句,自 12.0 以来已经有了很多性能改进,真的很难相信你最好落后 4 个版本。如果您发现某些情况需要链式索引以提高速度,您可能希望在此处发布该特定示例而不是此示例测试。我认为这里的某个人很可能会拥有一种与您使用链式索引所做的任何事情一样快的方法。

【讨论】:

  • 我刚刚用 pandas v 15.2(和 nrows=1000)做到了,我的链式仍然更快:0.117352962494 链式 1.13028311729 未链式 0.828242063522 未链式 0.102880001068 链式
  • @Eric -- 我不知道当时发生了什么。我刚刚复制并粘贴了您的代码(同样,nrows=1000 除外)
  • 很奇怪,我一直与你相反......
  • @Eric -- 显然我们中的一个疯了,我们必须从 Ed 或 DSM 那里获得第三个意见,以确定它是我们中的哪一个。 ;-)
  • @JohnE 这一切都很好,哈哈。我刚刚降级,链式速度更快,非链式速度更慢 =P ...
猜你喜欢
  • 2015-07-31
  • 1970-01-01
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 2022-11-01
  • 2018-04-21
  • 1970-01-01
相关资源
最近更新 更多