我已经构造了一些大数据框,它们对应于网络图中的联系人。这些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。
我有一些功能代码,它们遍历行,检查指定相邻节点的列,然后在数据框中查找它们的类型,并增加count列。这可以达到预期的效果,但是速度较慢。为了清楚起见,类型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。请注意,索引和标头是包含且重要的。将其加载为大熊猫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()
上,但也许是在这里...
答案 0 :(得分:0)
我没有找到一种向量化countNeighbors()
的有效方法,但是通过避免链式索引(请参阅Returning a view versus a copy),可以大致将执行时间减半(见{{3}})。 e。通过更改
cellType = contactMap[1][cellID]
contactMap[24+cellType][index] += 1
到
cellType = contactMap.at[cellID, 1]
contactMap.at[index, 24+cellType] += 1