加速对pandas数据帧的许多访问

时间:2016-11-15 19:48:24

标签: python pandas

我正在使用数据框存储有关哪些人服用哪种药物的信息。多索引中有大约16000行描述了人的特征,以及1000列不同的药物。 example table excerpt

我使用这个DataFrame来聚合数百万人的信息:对于每个人,我查询多个数据库并进行一些字符串解析以获取有关人的特征和他们服用的药物的信息。因此,我无法进行任何直接加入/合并。然后,对于那个人,我访问DataFrame以增加对应于患者的那一行中的值,跨越对应于患者药物的一组列:

decimal salaryGrade;
if(decimal.TryParse(dt.Tables[0].Rows[0]["SalaryGrade"], out salaryGrade))
{
    var salaryPerHour = salaryGrade/(22*8);
}

这是非常缓慢的,因为我按顺序为每个人这样做。因为我需要同时增加许多列" .at"没有用。是不是这种方式不使用Pandas的唯一解决方案,还是有另一种方法可以加速它?这个DataFrame只有大约250 Mb,所以像SQLite3这样的磁盘数据库看起来有点矫枉过正吗?

相关: Pandas DataFrame performance Pandas dataframe and speed

1 个答案:

答案 0 :(得分:2)

我使用了jeremycg的评论。我惊讶地发现聚合速度要快得多,数据框定义如下:

idx = pd.MultiIndex.from_product([range(10),range(10),range(10)['count','denom']], 
     names=['year','age','visits','type'])       
df = pd.DataFrame(np.zeros((len(idx),len(drugs))), index = idx, columns = drugs)
df = df.sort_index()

这需要大约3.6秒才能运行:

for i in range(1000):
    age = np.random.randint(0,10,1)[0]
    year = np.random.randint(0,10,1)[0]
    visits = np.random.randint(0,10,1)[0]
    drugs = [drugs[drug_i] for drug_i in np.random.permutation(len(drugs))[:50]]
    df.loc[(age, year, visits,'count'),drugs] += 1
    df.loc[(age, year, visits,'denom'),drugs] -= 1

这需要大约1.6秒才能运行:

aggmat = {d:np.zeros(2000) for d in ['age','year','visits'] + drugs}
aggmat['type'] = ['count','denom']*1000
for i in range(0,1000,2):
    aggmat['age'][i:(i+2)] = np.random.randint(0,10,1)[0]
    aggmat['year'][i:(i+2)] = np.random.randint(0,10,1)[0]
    aggmat['visits'][i:(i+2)] = np.random.randint(0,10,1)[0]
    for drug_i in np.random.permutation(len(drugs))[:50]:
       aggmat[drugs[drug_i]][i] = 1
       aggmat[drugs[drug_i]][i+1] = -1
z = pd.DataFrame(aggmat).groupby(['age','year','visits','type']).sum() 
df.loc[z.index,:] += z