【发布时间】: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(),但也许是这里的问题......
【问题讨论】:
-
你有一些很好的细节,但你能创建一个Minimal, Complete, and Verifiable example 供其他人使用吗?
-
@BradSolomon Here is a sample contact matrix。您应该能够将它直接导入到 Pandas 中,这里包含标头和索引的节点。我也会更新原帖。
标签: python-3.x pandas optimization vectorization