Pandas 在dataframe中查找模式,按行重新排序,并重置索引

Pandas 在dataframe中查找模式,按行重新排序,并重置索引,pandas,dataframe,indexing,pattern-matching,Pandas,Dataframe,Indexing,Pattern Matching,这是一个多部分问题。我已经为每个单独的部分找到了解决方案,但当我试图组合这些解决方案时,我没有得到我想要的结果 假设这是我的数据帧: df = pd.DataFrame(list(zip([1, 3, 6, 7, 7, 8, 4], [6, 7, 7, 9, 5, 3, 1])), columns = ['Values', 'Vals']) df Values Vals 0 1 6 1 3 7 2 6 7 3 7 9 4

这是一个多部分问题。我已经为每个单独的部分找到了解决方案,但当我试图组合这些解决方案时,我没有得到我想要的结果

假设这是我的数据帧:

df = pd.DataFrame(list(zip([1, 3, 6, 7, 7, 8, 4], [6, 7, 7, 9, 5, 3, 1])), columns = ['Values', 'Vals'])
df

    Values  Vals
0     1     6
1     3     7
2     6     7
3     7     9
4     7     5
5     8     3
6     4     1
假设我想在“值”列中找到模式[6,7,7]。 我可以使用此处给出的第二个解决方案的修改版本:

我发现将其缩小到索引值的唯一方法是:

pat_i = [df.index[i-len(pattern):i] # Get the index 
 for i in range(len(pattern), len(df)) # for each 3 consequent elements 
 if all(df['Values'][i-len(pattern):i] == pattern)] # if the pattern matched
pat_i

[RangeIndex(start=2, stop=5, step=1)]
一旦我找到了模式,我想在原始数据帧中做的是将模式重新排序为[7,7,6],在我这样做的同时移动所有相关行。换句话说,通过索引,我想得到如下输出:

df.reindex([0, 1, 3, 4, 2, 5, 6])

    Values  Vals
0     1     6
1     3     7
3     7     9
4     7     5
2     6     7
5     8     3
6     4     1
然后,最后,我想重置索引,以便所有列中的值都保留在新的重新排序的位置

    Values  Vals
0     1     6
1     3     7
2     7     9
3     7     5
4     6     7
5     8     3
6     4     1
为了使用
pat_i
作为重新排序的基础,我尝试修改这里给出的第二个解决方案:

但是,我不知道如何利用
pat_I
RangeIndex对象将其用于此代码。当我找到解决方案时,它将应用于数百个数据帧,每个数据帧都包含[6,7,7]模式,需要在一个位置重新排序,但不是在每个数据帧中的相同位置


感谢您的任何帮助……我相信一定有一种优雅的、像蟒蛇一样的方式来做到这一点,因为这似乎应该是一个足够普遍的挑战。谢谢。

我只是重写了你的代码。我将第一个和最后一个索引放在一边,对感兴趣的索引重新排序,并将所有内容放在一个新的索引中。然后我只使用新的索引对数据进行重新排序

import pandas as pd
from pandas import RangeIndex

df = pd.DataFrame(list(zip([1, 3, 6, 7, 7, 8, 4], [6, 7, 7, 9, 5, 3, 1])), columns = ['Values', 'Vals'])
pattern = [6, 7, 7]
new_order = [1, 2, 0] # new order of pattern

for i in list(df[df['Values'] == pattern[0]].index):
    if all(df['Values'][i:i+len(pattern)] == pattern):
        pat_i = df[i:i+len(pattern)]
front_ind = list(range(0, pat_i.index[0]))
back_ind = list(range(pat_i.index[-1]+1, len(df)))
pat_ind = [pat_i.index[i] for i in new_order]
new_ind = front_ind + pat_ind + back_ind
df = df.loc[new_ind].reset_index(drop=True)


谢谢看起来这应该是可行的,但它确实使用了for循环,这是我希望避免的。这只是一个示例数据帧;我将在其上使用代码的“现实生活”版本要大得多,而且有数百个,所以这可能会非常缓慢。但再次感谢你;您的解决方案可能会启发我做其他事情。请记住,一般来说,应用比for快,使用pandas向量比。应用和numpy比一切都快。如果您想要速度,我将更新我的答案,以锚定特定值中的循环。例如,在这个新答案中,只执行一个循环。谢谢。我得到了一个用于处理示例真实数据帧的解决方案的版本,但出于某种原因,我只修改了这一行:“if all(df['Values'][I:I+len(pattern)]==pattern)”改为:“if all(df['Family'][I-len(pattern):I]==pattern)”,不管什么都有效,尽管您的修改意味着您提供的模式是反向的。只需确保您完成了更改(例如,更改此:pat_i=df[i:i+len(模式)])。
target_row = 2
# Move target row to first element of list.
idx = [target_row] + [i for i in range(len(df)) if i != target_row]
import pandas as pd
from pandas import RangeIndex

df = pd.DataFrame(list(zip([1, 3, 6, 7, 7, 8, 4], [6, 7, 7, 9, 5, 3, 1])), columns = ['Values', 'Vals'])
pattern = [6, 7, 7]
new_order = [1, 2, 0] # new order of pattern

for i in list(df[df['Values'] == pattern[0]].index):
    if all(df['Values'][i:i+len(pattern)] == pattern):
        pat_i = df[i:i+len(pattern)]
front_ind = list(range(0, pat_i.index[0]))
back_ind = list(range(pat_i.index[-1]+1, len(df)))
pat_ind = [pat_i.index[i] for i in new_order]
new_ind = front_ind + pat_ind + back_ind
df = df.loc[new_ind].reset_index(drop=True)

df
Out[82]: 
   Values  Vals
0       1     6
1       3     7
2       7     9
3       7     5
4       6     7
5       8     3
6       4     1