gpt4 book ai didi

python - 使用 Pandas groupby 迭代和修改数据框

转载 作者:太空宇宙 更新时间:2023-11-03 15:09:31 24 4
gpt4 key购买 nike

我正在处理大量 1 的数组,需要系统地从数组的各个部分中删除 0。大数组由许多较小的数组组成,对于每个较小的数组,我需要系统地将其上下三角形替换为 0。例如,我们有一个数组,其中包含由索引值指示的 5 个子数组(所有子数组具有相同的列数):

     0    1    2
0 1.0 1.0 1.0
1 1.0 1.0 1.0
1 1.0 1.0 1.0
2 1.0 1.0 1.0
2 1.0 1.0 1.0
2 1.0 1.0 1.0
3 1.0 1.0 1.0
3 1.0 1.0 1.0
3 1.0 1.0 1.0
3 1.0 1.0 1.0
4 1.0 1.0 1.0
4 1.0 1.0 1.0
4 1.0 1.0 1.0
4 1.0 1.0 1.0
4 1.0 1.0 1.0

我希望在其上三角形和下三角形中修改每组行,以便生成的矩阵为:

      0    1    2
0 1.0 1.0 1.0
1 1.0 1.0 0.0
1 0.0 1.0 1.0
2 1.0 0.0 0.0
2 0.0 1.0 0.0
2 0.0 0.0 1.0
3 1.0 0.0 0.0
3 1.0 1.0 0.0
3 0.0 1.0 1.0
3 0.0 0.0 1.0
4 1.0 0.0 0.0
4 1.0 1.0 0.0
4 1.0 1.0 1.0
4 0.0 1.0 1.0
4 0.0 0.0 1.0

目前我只使用 numpy 来实现这个结果数组,但我认为我可以使用 Pandas 分组来加速它。实际上,我的数据集非常大,几乎有 500,000 行长。 numpy 代码如下:

import numpy as np

candidateLengths = np.array([1,2,3,4,5])
centroidLength =3

smallPaths = [min(l,centroidLength) for l in candidateLengths]

# This is the k_values of zeros to delete. To be used in np.tri
k_vals = list(map(lambda smallPath: centroidLength - (smallPath), smallPaths))
maskArray = np.ones((np.sum(candidateLengths), centroidLength))

startPos = 0
endPos = 0
for canNo, canLen in enumerate(candidateLengths):
a = np.ones((canLen, centroidLength))
a *= np.tri(*a.shape, dtype=np.bool, k=k_vals[canNo])
b = np.fliplr(np.flipud(a))
c = a*b

endPos = startPos + canLen

maskArray[startPos:endPos, :] = c

startPos = endPos

print(maskArray)

当我在真实数据集上运行此命令时,执行时间大约为 5-7 秒。我认为这归因于这个巨大的 for 循环。如何使用 pandas 分组来实现更高的速度?谢谢

最佳答案

新答案

def tris(n, m):
if n < m:
a = np.tri(m, n, dtype=int).T
else:
a = np.tri(n, m, dtype=int)
return a * a[::-1, ::-1]

idx = np.append(df.index.values, -1)
w = np.append(-1, np.flatnonzero(idx[:-1] != idx[1:]))
c = np.diff(w)
df * np.vstack([tris(n, 3) for n in c])

0 1 2
0 1.0 1.0 1.0
1 1.0 1.0 0.0
1 0.0 1.0 1.0
2 1.0 0.0 0.0
2 0.0 1.0 0.0
2 0.0 0.0 1.0
3 1.0 0.0 0.0
3 1.0 1.0 0.0
3 0.0 1.0 1.0
3 0.0 0.0 1.0
4 1.0 0.0 0.0
4 1.0 1.0 0.0
4 1.0 1.0 1.0
4 0.0 1.0 1.0
4 0.0 0.0 1.0

旧答案

我定义了一些辅助三角形函数

def tris(n, m):
if n < m:
a = np.tri(m, n, dtype=int).T
else:
a = np.tri(n, m, dtype=int)
return a * a[::-1, ::-1]

def tris_df(df):
n, m = df.shape
return pd.DataFrame(tris(n, m), df.index, df.columns)

然后

df * df.groupby(level=0, group_keys=False).apply(tris_df)

0 1 2
0 1.0 1.0 1.0
1 1.0 1.0 0.0
1 0.0 1.0 1.0
2 1.0 0.0 0.0
2 0.0 1.0 0.0
2 0.0 0.0 1.0
3 1.0 0.0 0.0
3 1.0 1.0 0.0
3 0.0 1.0 1.0
3 0.0 0.0 1.0
4 1.0 0.0 0.0
4 1.0 1.0 0.0
4 1.0 1.0 1.0
4 0.0 1.0 1.0
4 0.0 0.0 1.0

关于python - 使用 Pandas groupby 迭代和修改数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44345904/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com