Python 在数据帧中查找asc/desc序列

Python 在数据帧中查找asc/desc序列,python,pandas,Python,Pandas,我正在尝试构建一个工具,它将帮助简化研究工作,并且似乎需要检测一列数据中的递增序列和另一列中的asc/desc序列 有没有一种干净的方法来检查行中是否有序列,而不必编写一个状态机来遍历像这样的行?编写这样一段代码时,必须检查一列中的值是否在递增(无间隙),另一列中的值是否为asc/desc(无间隙)。我完全能够做到这一点,我只是想知道我的熊猫工具箱里是否有什么东西我遗漏了 这里有一些例子来阐明我的意图 import pandas as pd from collections import na

我正在尝试构建一个工具,它将帮助简化研究工作,并且似乎需要检测一列数据中的递增序列和另一列中的asc/desc序列

有没有一种干净的方法来检查行中是否有序列,而不必编写一个状态机来遍历像这样的行?编写这样一段代码时,必须检查一列中的值是否在递增(无间隙),另一列中的值是否为asc/desc(无间隙)。我完全能够做到这一点,我只是想知道我的熊猫工具箱里是否有什么东西我遗漏了

这里有一些例子来阐明我的意图

import pandas as pd 
from collections import namedtuple

QUERY_SEGMENT_ID_COLUMN = 'Query Segment Id'
REFERENCE_SEGMENT_ID_COLUMN = 'Reference Segment Id'

def dataframe(data):
    columns = [QUERY_SEGMENT_ID_COLUMN, REFERENCE_SEGMENT_ID_COLUMN]
    return pd.DataFrame(data, columns=columns)

# No sequence in either column. No results
data_without_pattern = [[1, 2], [7, 0], [3, 6]]

# Sequence in first column, but no sequence in second column. No results
data_with_pseodo_pattern_query = [[1, 2], [2, 0], [3, 6]]

# Sequence in second column, but no sequence in first column. No results
data_with_pseudo_pattern_reference = [[1, 2], [7, 3], [3, 4]]

# Broken sequence in first column, sequence in second column. No results
data_with_pseudo_pattern_query_broken = [[1, 2], [3, 3], [7, 4]]

# Sequence occurs in both columns, asc. Expect results
data_with_pattern_asc = [[1, 2], [2, 3], [3, 4]]

# Sequence occurs in both columns, desc. Expect results
data_with_pattern_desc = [[1, 4], [2, 3], [3, 2]]

# There is a sequence, and some noise. Expect results
data_with_pattern_and_noise = [[1, 0], [1, 4], [1, 2], [1, 3], [2, 3], [3, 4]]
在第一个例子中,没有任何模式

print(dataframe(data_without_pattern))
   Query Segment Id  Reference Segment Id
0                 1                     2
1                 7                     0
2                 3                     6
第二个示例在查询列中具有递增的ID序列,但在引用列中没有

print(dataframe(data_with_pseodo_pattern_query))
   Query Segment Id  Reference Segment Id
0                 1                     2
1                 2                     0
2                 3                     6
第三个示例与前一个示例相同,但用于参考列

print(dataframe(data_with_pseudo_pattern_reference))
   Query Segment Id  Reference Segment Id
0                 1                     2
1                 7                     3
2                 3                     4
在这里,引用列中有一个升序,而查询列中的ID也按升序排列,因此存在间隙,因此不需要任何结果

print(dataframe(data_with_pseudo_pattern_query_broken))
   Query Segment Id  Reference Segment Id
0                 1                     2
1                 3                     3
2                 7                     4
这里有两个“完美”示例,其中查询列按升序排列,未中断,引用列分别按降序和升序排列。预期会有结果

print(dataframe(data_with_pattern_asc))
   Query Segment Id  Reference Segment Id
0                 1                     2
1                 2                     3
2                 3                     4

print(dataframe(data_with_pattern_desc))
   Query Segment Id  Reference Segment Id
0                 1                     4
1                 2                     3
2                 3                     2
最终,一个数据不太干净但仍存在所需模式的案例

print(dataframe(data_with_pattern_and_noise))
   Query Segment Id  Reference Segment Id
0                 1                     0
1                 1                     4
2                 1                     2
3                 1                     3
4                 2                     3
5                 3                     4
这一最新案例可能需要进一步解释。我在这里的目标是返回类似于
q=(1,3),r=(2,4)
的内容,例如从相应的列(不是索引)返回
(开始,结束)

我在想是否有可能进行一系列很好的
groupby
操作,但我并没有看到树木中的树木

我认为这个问题具有社区价值,因为我找不到类似的问题,有人在多栏中寻找行的模式。

编辑:注释中的大小写(@code-different)

对于数据帧

data_with_multiple_contiguous_sequences = [[1, 1], [2, 2], [3, 3], [0, 4], [1, 5], [2, 6], [3, 7], [4, 8]]

   Query Segment Id  Reference Segment Id
0                 1                     1
1                 2                     2
2                 3                     3
3                 0                     4
4                 1                     5
5                 2                     6
6                 3                     7
7                 4                     8

目标是识别这两个序列。这意味着我们希望得到
q1=(1,3),r1=(1,3),q2=(0,4),r2=(4,8)
,如果我理解正确,您的问题是孤岛和缺口问题的变体。具有可接受间隙的每个单调(递增或递减)子序列将形成一个孤岛。例如,给定一个系列
s

s   island
--  ------
0   1
0   1
1   1
3   2        # gap > 1, form new island
4   2
2   3        # stop increasing, form new island
1   3 
0   3
概括来说:只要当前行和前一行之间的间隙超出[-1,1]范围,就会形成一个新的孤岛

查询段Id
参考段Id
上应用此间隙和孤岛算法:

Query Segment Id  Q Island    Reference Segment Id  R Island    Q-R Intersection
----------------  --------    --------------------  --------    ----------------
1                 1           1                     1           (1, 1)
2                 1           2                     1           (1, 1)
3                 1           3                     1           (1, 1)
0                 2           4                     1           (2, 1)
1                 2           5                     1           (2, 1)
2                 2           6                     1           (2, 1)
3                 2           7                     1           (2, 1)
4                 2           8                     1           (2, 1)
0                 3           9                     1           (3, 1)
您正在查找的
q
r
范围现在是每个
q-r交叉点开始和结束处的
查询段Id
参考段Id
。最后一个警告:忽略长度为1的交点(就像最后一个交点)


代码:

结果:

                   Q Start  Q End  R Start  R End  Count       Q       R
Q Island R Island                                                       
1        1               1      3        1      3      3  (1, 3)  (1, 3)
2        1               0      4        4      8      5  (0, 4)  (4, 8)

在最后一个例子中,
q=(1,3)
r=(2,4)
代表什么?每列递增/递减范围的起始和结束?如果在同一列中有多个连续的序列,比如
123014
,那么在这种情况下,返回值应该是什么呢?@code不同的好问题。我已经更新了这个问题,以澄清元组确实是范围的开始和结束。我不确定我是否理解你的第二个例子。我认为这取决于其他专栏的内容。但我会编辑这个问题,把它包括进去。漂亮,正确的解决方案。非常感谢。这“解锁”了我。我现在可以进一步处理这些岛屿,以讲述数据所讲述的故事。
                   Q Start  Q End  R Start  R End  Count       Q       R
Q Island R Island                                                       
1        1               1      3        1      3      3  (1, 3)  (1, 3)
2        1               0      4        4      8      5  (0, 4)  (4, 8)