优化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对象变成了元组。这就是正确的方法?@RazorXsrdata[ts.name]
应该可以自己工作。您可以使用git clone将一个元组传递给一个具有多索引的系列git://github.com/pydata/pandas.git然后运行python setup.py安装
?我看不到与@Jeff报告的性能级别相同的性能级别-可能是因为您的补丁尚未在我的构建版本中。