如何 select 排序数据

How to select sequenc data

我不知道如何开始过滤数据是 3 和更多序列 data.For 例如我的基本数据是 stevilo 列下的数字(188774, 18775,18814) 甚至超过 3 个(也许可以更改序列号(超过 3 个,超过 2 个或正好是第 3 个))。

    stevilo             cas F   
1   Pattern number : 1  B3341 
2   Pattern number : 2  B3342
7   18774               18.11.2019 11:07 
8   18775               18.11.2019 11:09 
8   18776               18.11.2019 11:20 
26  Pattern number : 1  B2633-CELA 
56  18814               18.11.2019 12:44 
57  18815               18.11.2019 12:45 
63  Pattern number : 1  B3343 
70  18819               18.11.2019 12:52 
76  Pattern number : 1  B1822A
327 19022               18.11.2019 19:21
328 19023               18.11.2019 19:23
329 19024               18.11.2019 19:25
330 19025               18.11.2019 19:26
331 19026               18.11.2019 19:27
332 19027               18.11.2019 19:28
333 19028               18.11.2019 19:30
334 19029               18.11.2019 19:31
335 19030               18.11.2019 19:32
345 19040               18.11.2019 19:46
346 19041               18.11.2019 19:48
349 19044               18.11.2019 20:21

我想复制数据,例如 3 个序列数据(19022、19023、19024),我的输出数据将像:

1   Pattern number : 1  B3341 
2   Pattern number : 2  B3342
7   18774               18.11.2019 11:07 
8   18775               18.11.2019 11:09 
8   18776               18.11.2019 11:20 
76  Pattern number : 1  B1822A
327 19022               18.11.2019 19:21
328 19023               18.11.2019 19:23
329 19024               18.11.2019 19:25
330 19025               18.11.2019 19:26
331 19026               18.11.2019 19:27
332 19027               18.11.2019 19:28
333 19028               18.11.2019 19:30
334 19029               18.11.2019 19:31
335 19030               18.11.2019 19:32

首先我们添加一个辅助列group 来指示该行属于哪个组(从'Pattern number ...' 行开始)。然后我们根据 stevilo 列中的数字将此列使用 find_pattern 函数转换为 True/False 指标:

  • 仅包含 header 且不包含数字(长度为 1)的组
  • 少于 4 行(包括 header 行)的组被排除在外
  • 所有剩余的组都(部分)包含在第一行,其中数字为 non-consequtive
def find_pattern(x):
    if len(x) == 1:
        return True
    if len(x) < 4:
        return False
    x = pd.to_numeric(x, 'coerce')
    diff = x.values - x.shift().values
    with np.errstate(invalid='ignore'):
        end = np.argwhere(diff > 1)
    if len(end) == 0:
        return True
    else:
        end = end[0][0]
        diff[:end] = True
        diff[end:] = False
        return diff

示例数据示例:

import pandas as pd
import numpy as np
import io

s = """    stevilo             cas F   
1   Pattern number : 1  B3341 
2   Pattern number : 2  B3342
7   18774               18.11.2019 11:07 
8   18775               18.11.2019 11:09 
8   18776               18.11.2019 11:20 
26  Pattern number : 1  B2633-CELA 
56  18814               18.11.2019 12:44 
57  18815               18.11.2019 12:45 
63  Pattern number : 1  B3343 
70  18819               18.11.2019 12:52 
76  Pattern number : 1  B1822A
327 19022               18.11.2019 19:21
328 19023               18.11.2019 19:23
329 19024               18.11.2019 19:25
330 19025               18.11.2019 19:26
331 19026               18.11.2019 19:27
332 19027               18.11.2019 19:28
333 19028               18.11.2019 19:30
334 19029               18.11.2019 19:31
335 19030               18.11.2019 19:32
345 19040               18.11.2019 19:46
346 19041               18.11.2019 19:48
349 19044               18.11.2019 20:21"""

df = pd.read_fwf(io.StringIO(s), [(0,3),(4,23),(24,222)]).set_index('Unnamed: 0')
del df.index.name

df['group'] = np.where(df.stevilo.str.startswith('Pattern'), df.index, np.nan)
df.group = df.group.ffill()

df.group = df.groupby('group').stevilo.transform(find_pattern).astype(bool)
res = df[df.group].drop('group',1)

print(res) 的输出:

                stevilo             cas F
1    Pattern number : 1             B3341
2    Pattern number : 2             B3342
7                 18774  18.11.2019 11:07
8                 18775  18.11.2019 11:09
8                 18776  18.11.2019 11:20
76   Pattern number : 1            B1822A
327               19022  18.11.2019 19:21
328               19023  18.11.2019 19:23
329               19024  18.11.2019 19:25
330               19025  18.11.2019 19:26
331               19026  18.11.2019 19:27
332               19027  18.11.2019 19:28
333               19028  18.11.2019 19:30
334               19029  18.11.2019 19:31
335               19030  18.11.2019 19:32

(如果多个组 header 行应具有相同的索引值,您必须将索引重置为范围索引并将此新索引用于组值)