首页 > 解决方案 > 如何根据特定列中特定值的每个转换来选择 DataFrame 中的行?

问题描述

我有一个 DataFrame,它的 ID 列和 Value 列仅包含 (0,1,2)。如果值列中存在从 (0-1) 或 (1-2) 的转换,我只想捕获那些行。这个过程必须分别为每个 ID 完成。

我尝试对 ID 进行 groupby 并使用差异聚合函数。这样我就可以采用值差为 1 的那些行。但在某些情况下它会失败。

df=df.loc[df['values'].isin([0,1,2])]
df = df.sort_values(by=['Id'])
df.value.diff()

给定数据框:

索引 UniqID 值

1 一 1

2个0

3 一 1

4个0

5一1

6一2

7 b 0

8 b 2

9 乙 1

10 乙 2

11 乙 0

12 乙 1

13 c 0

14 c 1

15 c 2

16 c 2

预期输出:

2个0

3 一 1

4个0

5一1

6一2

9 乙 1

10 乙 2

11 乙 0

12 乙 1

13 c 0

14 c 1

15 c 2

仅当从 0-1 或 1-2 转换时才期望这些行。

先感谢您。

标签: python-3.xpandasdataframedata-sciencedata-manipulation

解决方案


将此我的解决方案用于具有模式元组的组:

np.random.seed(123)

N = 100
d = {
    'UniqID': np.random.choice(list('abcde'), N),
    'Value': np.random.choice([0,1,2], N),
}
df = pd.DataFrame(d).sort_values('UniqID')
#print (df)

pat = [(0, 1), (1, 2)]

a = np.array(pat)

s = (df.groupby('UniqID')['Value']
       .rolling(2, min_periods=1)
       .apply(lambda x: np.all(x[None :] == a, axis=1).any(), raw=True))

mask = (s.mask(s == 0)
         .groupby(level=0)
         .bfill(limit=1)
         .fillna(0)
         .astype(bool)
         .reset_index(level=0, drop=True))

df = df[mask]

print (df)
   UniqID  Value
99      a      1
98      a      2
12      a      1
63      a      2
38      a      0
41      a      1
9       a      1
72      a      2
64      b      1
67      b      2
33      b      0
68      b      1
57      b      1
71      b      2
10      b      0
8       b      1
61      c      1
66      c      2
46      c      0
0       c      1
40      c      2
21      d      0
74      d      1
15      d      1
85      d      2
6       d      1
88      d      2
91      d      0
83      d      1
4       d      1
34      d      2
96      d      0
48      d      1
29      d      0
84      d      1
32      e      0
62      e      1
37      e      1
55      e      2
16      e      0
23      e      1

推荐阅读