pandas - 在 pandas 数据框中查找模式,按行重新排序,并重置索引
问题描述
这是一个多部分问题。我已经为每个单独的部分找到了解决方案,但是当我尝试组合这些解决方案时,我没有得到我想要的结果。
假设这是我的数据框:
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]。我可以使用这里给出的第二个解决方案的修改版本: Pandas: How to find a specific pattern in a dataframe column?
pattern = [6, 7, 7]
pat_i = [df[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
[ Values Vals
2 6 7
3 7 9
4 7 5]
我发现将其缩小到仅索引值的唯一方法如下:
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
用作重新排序的基础,我尝试修改此处给出的第二个解决方案:
Python Pandas: How to move one row to the first row of a Dataframe?
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]
但是,我不知道如何利用pat_i
RangeIndex 对象将其与此代码一起使用。解决方案,当我找到它时,将应用于数百个数据帧,每个数据帧都将包含需要在一个位置重新排序的 [6, 7, 7] 模式,但每个数据帧中的位置不同.
任何帮助表示赞赏......而且我确信必须有一种优雅的、pythonic 的方式来做到这一点,因为它似乎应该是一个足够普遍的挑战。谢谢你。
解决方案
我只是重写了你的代码。我将第一个和最后一个索引放在一边,重新排序感兴趣的索引,然后将所有内容放在一个新索引中。然后我只使用新索引对数据进行重新排序。
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
推荐阅读
- c++ - 如何从 .txt 文件中读取 CSV 列表并将每个项目分隔到它们自己的数组中
- highcharts - highchart 导出按钮不显示
- c++ - C++:为什么这个基本的 2D Quickhull 算法以错误的顺序返回点?
- salesforce - 为什么我不能在 Salesforce Marketing Cloud 中创建多个 LookupRows?
- r - R read_excel:libxls错误:无法解析文件
- linux - 有没有办法将由 printk 消息构建的输出通过管道传输到控制台上的 grep?
- jq - jq - |= 运算符如何工作?
- c++ - 减少随机播放算法中调用rand的次数
- c# - 在 .NET MVC 应用程序中验证 Azure AD B2C JWT
- c++ - 单目总捕获编译过程错误:Makefile:83: recipe for target 'CMakeFiles/mylib.dir/all' failed