【问题标题】:How can I vectorize checking values in each row of DataFrame for a "kind" and updating a count?如何对 DataFrame 每一行中的“种类”检查值进行矢量化并更新计数?
【发布时间】:2019-05-13 21:23:09
【问题描述】:

我已经构建了一些与网络图中的联系人相对应的大型数据框。这些 DataFrame 的格式是行,其中索引值是图中节点的唯一标识符,第 1 列是对应于节点“类型”的整数(您可以将其视为类似于颜色的东西,例如,所有类型 1 都是红色的):

import pandas as pd
df = pd.read_csv( 
    "https://gist.githubusercontent.com/ethanagbaker/98062ebc83b3dd2018a1837d3e3b12df/raw/a59cb7645f6ca935e01a8dea04377da28847c365/testData.csv", 
    skiprows=1, header=None, index_col=0 
) 

第 3-24 列是与行索引指定的节点共享一条边的节点的 ID,0 表示没有邻居。因此,如果第 1 行中的第 3 列和第 4 列具有非零值,则节点 1 对这些指定节点具有边。第 25-32 列旨在为索引指定的节点指定每种类型的相邻节点的数量,并初始化为零。以下是此数据的示例:https://imgur.com/LtKRM38。节点 1 属于类型 6,有 6 个邻居:373、389、175、99、127 和 167。

我有迭代行的功能代码,检查指定相邻节点的列,然后在数据框中查找它们的类型,并增加计数列。这可以达到预期的效果,但速度很慢。为清楚起见,n 类型的计数在列n + 24 中。在 500 行的帧上运行时间约为 4 分钟,但我需要将其扩展到 ~50,000,000 行。我一直在尝试修改它以使用.apply() 或矢量化方法,但不太清楚如何做到这一点。这是功能齐全的迭代方法:

def countNeighbors(contactMap):
    for index, row in contactMap.iterrows():
        for col in range(3,25):
            cellID = row[col]
            if cellID == 0:
                break
            else:
                cellType = contactMap[1][cellID]
                contactMap[24+cellType][index] += 1
    return contactMap

#run the function
contactMapCounted = countNeighbors(contactMap)

contactMap 是上述矩阵,我导出了一个sample one here。请注意,索引和标题是包含且重要的。将其加载为 pandas DataFrame 应该允许您复制它。

我想我已经盯着这个看很久了,想看看在这里做什么,但是有没有明显的方法可以加快这个速度?

可能相关的编辑:经过更深入的测试,似乎单独使用此功能相当快,但我以以下方式使用它,这是我注意到明显放缓的地方:

n_shuffles = 100
while s < n_shuffles:
        #print(s)
        contactMap_Shuffled = contactMap.sample(frac=1).reset_index(drop=True)
        contactMap_Shuffled.index += 1
        contactMap_Shuffled.loc[:,25:] = 0  #Reset the count cols
        contactMap_Shuffled = countNeighbors(contactMap_Shuffled)
        s += 1

这是为了随机化帧的索引,然后按照描述重新计算计数值。这是我第一次注意到速度变慢的地方,我认为问题出在countNeighbors(),但也许是这里的问题......

【问题讨论】:

标签: python-3.x pandas optimization vectorization


【解决方案1】:

我没有找到矢量化countNeighbors() 的有效方法,但可以通过避免链式索引(参见Returning a view versus a copy)将执行时间大致减半,即。 e.通过改变

                cellType = contactMap[1][cellID]
                contactMap[24+cellType][index] += 1

                cellType = contactMap.at[cellID, 1]
                contactMap.at[index, 24+cellType] += 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 2017-09-26
    • 2021-02-07
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多