大索引数据集中Pandas.loc超慢

2024-09-28 01:32:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我是熊猫的新手,所以假设我一定错过了一些明显的东西

摘要:

我有一个300K+行的数据帧。我检索一行新数据,这些数据可能与DF中的现有行子集相关,也可能与DF中的现有行子集无关(由组ID标识),检索现有组ID或生成新的组ID,最后将其与组ID一起插入

熊猫似乎对此反应很慢

请告知:我遗漏了什么/我应该使用其他东西吗

详细信息:

列包括(示例):

columnList =    ['groupID','timeStamp'] + list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')

每个groupID可以有许多唯一的时间戳

groupID是内部生成的:

  1. 或者使用现有数据(通过将行与现有数据相匹配,例如通过列“D”进行匹配)
  2. 生成新的groupID

因此(至少在我看来)我不能批量更新/插入,我必须逐行更新/插入

我使用了一个SQL DB类比来创建一个索引,作为groupID和timeStamp的concat(我尝试了MultiIndex,但它似乎更慢)

最后,我使用.loc(ind,columnName)插入/更新

代码:

import pandas as pd
import numpy as np
import time 

columnList =    ['groupID','timeStamp'] + list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')

columnTypeDict = {'groupID':'int64','timeStamp':'int64'}

startID = 1234567

df = pd.DataFrame(columns=columnList)
df = df.astype(columnTypeDict)

fID = list(range(startID,startID+300000))

df['groupID'] = fID

ts = [1000000000]*150000 + [10000000001]*150000

df['timeStamp'] = ts

indx = [str(i) + str(j) for i, j in zip(fID, ts)] 

df['Index'] = indx
df['Index'] = df['Index'].astype('uint64')
df = df.set_index('Index')

startTime = time.time()

for groupID in range(startID+49000,startID+50000) :

    timeStamp = 1000000003

    # Obtain/generate an index
    ind =int(str(groupID) + str(timeStamp))


    #print(ind)
    df.loc[ind,'A'] = 1


print(df)

print(time.time()-startTime,"secs")

如果索引列已经存在,则其速度很快,但如果不存在,则10000次插入需要140秒


Tags: 数据importiddfindextimetimestamplist
1条回答
网友
1楼 · 发布于 2024-09-28 01:32:39

我认为访问数据帧是一个相对昂贵的操作。 您可以暂时保存这些值,并使用它们创建将与原始数据框合并的数据框,如下所示:

startTime = time.time()

temporary_idx = []
temporary_values = []

for groupID in range(startID+49000,startID+50000) :

    timeStamp = 1000000003

    # Obtain/generate an index
    ind = int(str(groupID) + str(timeStamp))
    temporary_idx.append(ind)
    temporary_values.append(1)

# create a dataframe with new values and apply a join with the original dataframe
df = df.drop(columns=["A"])\
    .merge(
        pd.DataFrame({"A": temporary_values}, index=temporary_idx).rename_axis("Index", axis="index"),
        how="outer", right_index=True, left_index=True
    )
print(df)
print(time.time()-startTime,"secs")

当我进行基准测试时,这需要less than 2 seconds来执行

我不知道您真正的用例是什么,但这是针对插入列A的情况,正如您在示例中所述。如果您的用例比这更复杂,那么可能有更好的解决方案

相关问题 更多 >

    热门问题