是否有一些有效的方法来找到行满足的条件,这些条件引用了下几行中的值?

2024-06-30 15:02:32 发布

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

我想寻找在数据帧中找到满足某些条件的行的有效方法。 数据帧有n行3列。值为-101
我想找到满足两个条件的行。你知道吗

  1. 条件:行的值(row0)!=-1
  2. 条件:由下3行生成的数组的对角线(行1,行2,行3)=1。你知道吗

我使用loop方法遍历所有行并找到符合条件的行。但是,这并不是一个有效的方法,尤其是当有一个大的数据帧,这一步只是第一步。你知道吗

# Given a dataframe (n*3) 

randNum=random.choices(range(-1,2),k=333) # k=3*int
frame=pd.DataFrame(np.array(randNum).reshape(-1,3))

# its values = -1,0,1, like this:
# In [126]:frame
# Out[126]:
#     0  1  2
# 0    1  0  0
# 1    1 -1  1
# 2    1  1  1
# 3   -1 -1  1
# 4   -1  0 -1
# 5    1  1 -1
# ...
# 105 -1 -1 -1
# 106 -1 -1  0
# 107 -1 -1  0
# 108  0 -1  1
# 109 -1  0  1
# 110  1  0  1
#  I want find the row(s) that all of the values of
#  columns('0','1','2')!=-1, and while the value of 
#  the diagonal of next three rows =1, like this:
#       0  1  2
# row0  v1 v2 v3     # v1!=v2!=v3!=-1, it may be 1 or 0.
# row1   1  v  v
# row2   v  1  v          # v =-1 or 0 or 1
# row3   v  v  1
# the diagonal of rows (row1,row2,row3)=1

我想在数据帧中找到行0。它可以用循环法来解决,但是否存在一个有效的解决方案?谢谢!你知道吗


Tags: orofthe数据方法this条件frame
3条回答
randNum=random.choices(range(-1,2),k=333) # k=3*int
df=pd.DataFrame(np.array(randNum).reshape(-1,3))

# `D2` represents the second diagonal (init to -100 to handle last two rows)
# `D3` represents the third diagonal (init to -100 to handle last two rows)
df['D2'] = df['D3'] = -100
df['D2'][0:-1] = df[1][1:]
df['D3'][0:-2] = df[2][2:]
df[(df[0] != -1) & (df[1]!= -1) & (df[2] != -1) & (df[0] + df['D2'] + df['D3'] == 3)]

逻辑:

  1. 对于任何一行,第二个对角线值总是在第1列(D2)中
  2. 对于任何一行,第三个对角线值总是在第2列(D3)中
  3. 现在可以归结为检查[0] + [D2] + [D3] == 3

可以使用布尔掩码来表示每个单独的条件。第一个很简单:

c1_mask = frame[0] != -1

# edited version:
c1_mask = (frame!=-1).all(axis=1)

第二个问题可以通过卷积运算来解决

from scipy.signal import convolve2d

c2_mask = convolve2d(frame.values, np.eye(3), mode='valid')
c2_mask = (np.vstack([c2_mask, np.zeros((3, 1))]) == 3).reshape(-1)

# edited version:
c2_kernal = np.vstack((np.zeros((1,3)), np.eye(3)))
c2_mask = convolve2d(frame.values, c2_kernal, mode='valid')
c2_mask = (c2_mask == 3).reshape(-1)

然后把它们结合起来:

frame[c1_mask & c2_mask]

# edited version:
(frame[:-3])[(c1_mask[:-3]).shift[-1] & c2_mask]

注意,在这个解决方案中,列数只是一个参数,因此它可以很容易地扩展。你知道吗

第一个条件:

v1=df[df[0]=!1 & df[1]=!1 & df[2]=!1].index.tolist()

第二个条件:

v2=[]
for i in v1:
     if df[0][i+1]==1 and df[1][i+2]==1 and df[1][i+3]==1:
         v2.append(i)

要查看感兴趣行的索引,请执行以下操作:

print(v2)

要访问这些df块中的第一个,请执行以下操作:

df.loc[[v2[0],v2[0]+1,v2[0]+2,v2[0]+3]]

相关问题 更多 >