优化Python代码-由于pandas.core.series.series.\uu getitem带来的开销__

优化Python代码-由于pandas.core.series.series.\uu getitem带来的开销__,python,optimization,pandas,Python,Optimization,Pandas,我有pandas数据对象-数据,它存储为系列的系列。第一个系列在ID1上编制索引,第二个系列在ID2上编制索引 ID1 ID2 1 10259 0.063979 14166 0.120145 14167 0.177417 14244 0.277926 14245 0.436048 15

我有
pandas
数据对象-
数据
,它存储为系列的系列。第一个系列在
ID1
上编制索引,第二个系列在
ID2
上编制索引

ID1      ID2
1        10259           0.063979
         14166           0.120145
         14167           0.177417
         14244           0.277926
         14245           0.436048
         15021           0.624367
         15260           0.770925
         15433           0.918439
         15763           1.000000
...
1453     812690          0.752274
         813000          0.755041
         813209          0.756425
         814045          0.778434
         814474          0.910647
         814475          1.000000
Length: 19726, dtype: float64
我有一个函数,它使用这个对象的值进行进一步的数据处理。以下是函数:

#Function
def getData(ID1, randomDraw): 
    dataID2 = data[ID1]
    value = dataID2.index[np.searchsorted(dataID2, randomDraw, side='left').iloc[0]]
    return value
我使用
np.vectorize
将此函数应用于大约有2200万行的
DataFrame
-
DataFrame

dataFrame['ID2'] = np.vectorize(getData)(dataFrame['ID1'], dataFrame['RAND'])
其中,
ID1
RAND
是具有输入函数的值的列

这段代码大约需要6个小时来处理所有内容。在
Java
中,类似的实现只需大约6分钟即可完成2200万行数据

在我的程序上运行探查器时,我发现最昂贵的调用是对
数据进行索引
,其次是
searchsorted

Function Name: pandas.core.series.Series.__getitem__
Elapsed inclusive time percentage: 54.44

Function Name: numpy.core.fromnumeric.searchsorted  
Elapsed inclusive time percentage: 25.49    
使用
data.loc[ID1]
获取数据会使程序运行得更慢。我怎样才能使它更快?我知道
Python
无法实现与Java相同的效率,但6小时与6分钟相比似乎相差太大。也许我应该使用不同的数据结构/函数?我使用的是
python2.7
PTVS
IDE

添加一个最低限度的工作示例:

import numpy as np
import pandas as pd

np.random.seed = 0

#Creating a dummy data object - Series within Series
alt = pd.Series(np.array([ 0.25, 0.50,  0.75,  1.00]), index=np.arange(1,5))
data = pd.Series([alt]*1500, index=np.arange(1,1501))

#Creating dataFrame - 
nRows = 200000
d = {'ID1': np.random.randint(1500, size=nRows) + 1
     ,'RAND': np.random.uniform(low=0.0, high=1.0, size=nRows)}
dataFrame = pd.DataFrame(d)

#Function
def getData(ID1, randomDraw): 
    dataID2 = data[ID1]
    value = dataID2.index[np.searchsorted(dataID2, randomDraw, side='left').iloc[0]]
    return value

dataFrame['ID2'] = np.vectorize(getData)(dataFrame['ID1'], dataFrame['RAND'])

使用此代码可以获得更好的性能:

>>> def getData(ts):
...     dataID2 = data[ts.name]
...     i = np.searchsorted(dataID2.values, ts.values, side='left')
...     return dataID2.index[i]
... 
>>> dataFrame['ID2'] = dataFrame.groupby('ID1')['RAND'].transform(getData)

尝试在ID值上设置索引这将大大加快查找速度它是在ID值上建立索引的。plz在数据上应用
getData
的位置显示相关代码-frame@behzad.nouri:补充你应该说明你的实际问题是什么。看起来你需要做一个简单的合并。很棒的代码-工作非常快,因为查找顺序不在
groupby
级别。是否可以将此扩展到多列分组?说
ID0
ID1
,其中
dataID2
data[ID0][ID1]
@RazorXsr yes,但由于组的数量,速度会较慢。您可能还需要更新到master,请参见“确定”。因此,对于多列情况,我转换了
dataID2=data[ts.name[0]][ts.name[1]]
,因为ts.name对象变成了元组。这就是正确的方法?@RazorXsr
data[ts.name]
应该可以自己工作。您可以使用git clone将一个元组传递给一个具有多索引的系列git://github.com/pydata/pandas.git然后运行
python setup.py安装
?我看不到与@Jeff报告的性能级别相同的性能级别-可能是因为您的补丁尚未在我的构建版本中。