按“种类”计算值并用该计数更新数据帧中的值的更快方法?

2024-10-02 00:37:30 发布

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

我试图在脚本中实现一个步骤,在该步骤中,我在每一行中查找存储在同一数据帧中的值的“种类”,并更新每一行中每个“种类”有多少个值的计数。下面是一个玩具示例:

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。 有没有更快的方法来达到同样的效果?如果需要,我愿意重新设计数据结构,但是这种格式很方便


Tags: 数据对象inid类型dataframedfindex
1条回答
网友
1楼 · 发布于 2024-10-02 00:37:30

方案1:

type_dict = df.set_index(0)[1].to_dict()

for i in [3,4]:
    s = df[i].map(type_dict)
    df.loc[:,[5,6]] += pd.get_dummies(s)[[1,2]].values

方案2:

df.loc[:,[5,6]] = (pd.get_dummies(df[[3,4]]
                     .stack().map(type_dict))
                     .sum(level=0)
                  )

输出:

    0   1   2   3   4   5   6
1   1   1   1   2   0   1   0
2   2   1   1   1   0   1   0
3   3   2   2   8   4   1   1
4   4   2   2   3   9   1   1
5   5   1   1   6   0   1   0
6   6   1   1   5   0   1   0
7   7   2   1   10  0   0   1
8   8   1   1   3   0   0   1
9   9   1   2   4   10  0   2
10  10  2   2   7   9   1   1

相关问题 更多 >

    热门问题