首页 > 解决方案 > 使用特定条件查找数据框的特定部分

问题描述

我有一个看起来像这样的数据框:

>>> data = {'Count':[15, 21, 1, 7, 6, 1, 25, 8, 56, 0, 5, 9, 0, 12, 12, 8, 7, 12, 0, 8]}
>>> df = pd.DataFrame(data)
>>> df
    Count
0      15
1      21
2       1
3       7
4       6
5       1
6      25
7       8
8      56
9       0
10      5
11      9
12      0
13     12
14     12
15      8
16      7
17     12
18      0
19      8

我需要在这个df中添加两列来检测“洪水”。“洪水”定义为从“计数”超过 10 的行开始,直到“计数”下降到 5 以下。所以,在这种情况下,我想要这样的结果:

    Count   Flood   FloodNumber
0      15    True             1
1      21    True             1
2       1   False             0
3       7   False             0
4       6   False             0
5       1   False             0
6      25    True             2
7       8    True             2
8      56    True             2
9       0   False             0
10      5   False             0
11      9   False             0
12      0   False             0
13     12    True             3
14     12    True             3
15      8    True             3
16      7    True             3
17     12    True             3
18      0   False             0
19      8   False             0

我设法用这样的简单循环添加了我的“洪水”列:

df.loc[0, 'Flood'] = (df.loc[0, 'Count'] > 10)
for index in range(1, len(df)):
    df.loc[index, 'Flood'] = ((df.loc[index, 'Count'] > 10) | ((df.loc[index-1, 'Flood']) & (df.loc[index, 'Count'] > 5)))

,但这似乎是一种极其缓慢和愚蠢的做法。有没有使用熊猫函数而不是循环的“正确”方法?

标签: pythonpython-3.xpandas

解决方案


要查找Flood标志,我们可以使用掩码和ffill().

df['Flood'] = ((df.Count > 10).where(df.Count > 10)
               .fillna((df.Count > 5)
                       .where(df.Count < 5))
               .ffill()
               .astype(bool))

要获得FloodNumber,让我们忽略列中的所有行FalseFloodgroupby+cumsum

s = df.Flood.where(df.Flood)
df.loc[:, 'FloodNumber'] = s.dropna().groupby((s != s.shift(1)).cumsum()).ngroup().add(1)

输出

    Count  Flood  FloodNumber
0      15   True          1.0
1      21   True          1.0
2       1  False          NaN
3       7  False          NaN
4       6  False          NaN
5       1  False          NaN
6      25   True          2.0
7       8   True          2.0
8      56   True          2.0
9       0  False          NaN
10      5  False          NaN
11      9  False          NaN
12      0  False          NaN
13     12   True          3.0
14     12   True          3.0
15      8   True          3.0
16      7   True          3.0
17     12   True          3.0
18      0  False          NaN
19      8  False          NaN

推荐阅读