这是关于有效地在熊猫数据框中找到“ 2D形状”。我们生成了这样的框架:
l = ['>','<','v','^']
def gendf(r,c):
return pd.DataFrame(np.random.choice(l,size=(r,c)),columns=[i for i in range(c)])
我正在寻找以下形状:
^
< ? >
v
带有“?”是任何角色。我有一个效率很低的嵌套循环,可以慢慢地完成工作:
def co(df):
c=[]
for i in list(df.index)[:-2]:
for j in list(df.columns)[1:-1]:
if df.loc[i,j]=='^':
if df.loc[i+2,j]=='v' and df.loc[i+1,j-1]=='<' and df.loc[i+1,j+1]=='>':
c.append((i,j))
return c
它只是寻找“顶部”,并在找到它时检查其余部分。作为嵌套循环,它非常慢-任何功能都可以让我更有效地执行此操作吗?
编辑:给定方法的计时器
%timeit co(df)
8.08 s ± 260 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit x1(df) #Chris A's method
1.89 s ± 102 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit x2(df) #sampers' method
6.22 s ± 289 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
让我知道是否还有更好的方法-这已经很有帮助了!
答案 0 :(得分:4)
答案 1 :(得分:1)
将所有内容投射到列表上在计算上很繁琐。使用iat获取1个元素也比loc快。
按照您要求的禁食解决方案,尽管它可能不是最干净的解决方案:
def search(df):
result = []
for i in range(z.shape[0] - 2):
for j in range(1, z.shape[1] - 1):
if z.iat[i,j] == '^' and z.iat[i+2, j]=='v' and z.iat[i+1 ,j-1]=='<' and z.iat[i+1, j+1]=='>':
result.append((i+1,j))
return result
将其与其他解决方案进行计时:
%timeit other_solution(df)
2.67 s ± 152 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit search(df)
12.4 ms ± 836 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)