我试图在脚本中实现一个步骤,在该步骤中,我在每一行中查找存储在同一数据帧中的值的“种类”,并更新每一行中每个“种类”有多少个值的计数。下面是一个玩具示例:
d = {0: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
1: [1, 1, 2, 2, 1, 1, 2, 1, 1, 2],
2: [1, 1, 2, 2, 1, 1, 1, 1, 2, 2],
3: [2, 1, 8, 3, 6, 5, 10, 3, 4, 7],
4: [0, 0, 4, 9, 0, 0, 0, 0, 10, 9],
5: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
6: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
df = pd.DataFrame(d)
df.index += 1
在df
中,df[0]
包含对象的唯一ID,df[1]
,包含“kind”(这可能类似于对象的颜色)df[3]
和df[4]
包含感兴趣的相邻对象(0是占位符值,任何非零值都是相邻对象的ID,因此这里有1个或2个相邻对象)df[5]
和df[6]
用于存储每种类型的对象数量。这里只有两种类型,即int,因此类型1的相邻对象的计数进入df[5]
,类型2的相邻对象进入df[6]
我的工作代码遍历行和相邻的对象列,查找类型,然后递增相应的列。但是,这并不能很好地扩展,我的实际数据集有更多的行和对象类型,并且这个操作作为montecarlo类型模拟的一部分被重复调用。我不太确定在这里可以做些什么来加速它,我只尝试了ID:Type的字典查找,但实际上速度比较慢。以下是功能代码:
def countNeighbors(contactMap): #in case of subgraph, still need to know the neighbors type
for index, row in contactMap.iterrows():
for col in range(3,4):
cellID = row[col]
if cellID == 0:
pass
else:
cellType = int(contactMap[contactMap[0] == cellID][1])
contactMap.at[index, 4+cellType] += 1
return contactMap
df = countNeighbors(df)
预期产量:
output = {0: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 1: [1, 1, 2, 2, 1, 1, 2, 1, 1, 2], 2: [1, 1, 2, 2, 1, 1, 1, 1, 2, 2], 3: [2, 1, 8, 3, 6, 5, 10, 3, 4, 7], 4: [0, 0, 4, 9, 0, 0, 0, 0, 10, 9], 5: [1, 1, 1, 0, 1, 1, 0, 0, 0, 0], 6: [0, 0, 0, 1, 0, 0, 1, 1, 1, 1]}
out_df = pd.DataFrame(output)
out_ df.index += 1
所以要清楚,这个输出意味着对象1(行1)是类型1,有1个相邻的对象,对象2。我们在df
中查找对象2,发现它是类型1,所以增加列5。
有没有更快的方法来达到同样的效果?如果需要,我愿意重新设计数据结构,但是这种格式很方便
方案1:
方案2:
输出:
相关问题 更多 >
编程相关推荐