pandas 从两个连续值满足条件到另外两个连续值,标记为True

bqjvbblv  于 2023-03-06  发布在  其他
关注(0)|答案(4)|浏览(133)

我在 Dataframe 中有一个浮点列。我想添加另一个布尔列,如果条件满足两个连续值,则该列为True,直到另一个条件满足下两个连续值。
例如,我有一个 Dataframe ,它看起来像这样:
| 指标|数值%|
| - ------|- ------|
| 无|无|
| 1个|五个|
| 第二章|十一|
| 三个|九|
| 四个|十四|
| 五个|十八|
| 六个|三十|
| 七|五十四|
| 八个|七十三|
| 九|一百|
| 十个|一百|
| 十一|一百|
| 十二|一百|
| 十三|一百|
现在,我想从两个连续值满足条件df['Values %'] >= 10的位置标记为True,直到下两个连续值满足下一个条件,即df[Values %] == 100
所以最终的结果看起来像这样:
| 指标|数值%|旗帜|
| - ------|- ------|- ------|
| 无|无|假|
| 1个|五个|假|
| 第二章|十一|假|
| 三个|九|假|
| 四个|十四|假|
| 五个|十八|真的|
| 六个|三十|真的|
| 七|五十四|真的|
| 八个|七十三|真的|
| 九|一百|真的|
| 十个|一百|真的|
| 十一|一百|假|
| 十二|一百|假|
| 十三|一百|假|

rqenqsqc

rqenqsqc1#

不知道你的问题的第二部分是如何工作的,但这里是如何实现第一部分。

    • 示例数据**
s = pd.Series([0,5,11,9,14,18,2,14,16,18])
    • 解决方案**
# create true/false series for first condition and take cumulative sum
x = (s >= 10).cumsum()

# compare each element of x with 2 elements before.  There will be a difference of 2 for elements which belong to streak of 2 or more True
condition = x - x.shift(2) == 2

condition看起来像这样

0    False
1    False
2    False
3    False
4    False
5     True
6    False
7    False
8     True
9     True
dtype: bool
ybzsozfc

ybzsozfc2#

我有一个效率很低的方法。它不是矢量化的,所以不理想,但它很有效:

# Convert the values column to a 1D NumPy array for ease of use.
values = df["Values %"].tolist()
values_np = np.array(values)

# Initialize flags 1D array to be the same size as values_np. Initially set to all 0s. Uses int form of booleans, i.e. 0 = False and 1 = True.
flags = np.zeros((values_np.shape[0]), dtype=int)

# Iterate from 1st (not 0th) row to last row.
for i in range(1, values_np.shape[0]):
    # First set flag to 1 (True) if meets the condition that consecutive values are both >= 10.
    if values_np[i] >= 10 and values_np[i-1] >= 10:
        flags[i] = 1

    # Then if consecutive values are both larger than 100, set flag to 0 (False).
    if values_np[i] >= 100 and values_np[i-1] >= 100:
        flags[i] = 0

# Turn flags into boolean form (i.e. convert 0 and 1 to False and True).
flags = flags.astype(bool)

# Add flags as a new column in df.
df["Flags"] = flags

有一件事--我的方法为第10行给出False,因为第9行和第10行都〉= 100。如果这不是您想要的,请告诉我,我可以更改它,使标志只有在前两个值 * 和 * 当前值(3个连续值)都〉= 100时才为True。

kqlmhetl

kqlmhetl3#

def function1(dd:pd.DataFrame,Flag,pos=2):
    if(len(dd)>2):
        df1.loc[dd.iloc[pos].name,'Flag']=Flag

df11=df1.assign(col1=(~(df1['Values%'].ge(10))).cumsum()).groupby('col1').apply(function1,Flag=True)\
    .assign(col2=(~(df1['Values%'].eq(100))).cumsum()).groupby('col2').apply(function1,Flag='e',pos=3)\
    .pipe(lambda dd:df1).ffill()
df11.assign(Flag=df11.Flag.mask(df11.Flag.ne(True),False))

输出:

Values%   Flag
0         0  False
1         5  False
2        11  False
3         9  False
4        14  False
5        18   True
6        30   True
7        54   True
8        73   True
9       100   True
10      100   True
11      100  False
12      100  False
13      100  False
mftmpeh8

mftmpeh84#

您可以用途:

# give 2 consecutive values ≥ 10
m1 = df['Values %'].ge(10).rolling(2).min().eq(1)
# give 2 consecutive 100
m2 = df['Values %'].eq(100).rolling(2).min().eq(1)
# get values before (including) first m2 True
m3 = (~m2).shift(fill_value=True).cummin()

# get values between the first m1 True 
df['Flag'] = m1.cummax() & m3

输出:

index  Values %   Flag
0       0         0  False
1       1         5  False
2       2        11  False
3       3         9  False
4       4        14  False
5       5        18   True
6       6        30   True
7       7        54   True
8       8        73   True
9       9       100   True
10     10       100   True
11     11       100  False
12     12       100  False
13     13       100  False

如果需要在多个组上重复此逻辑:

# give 2 consecutive values ≥ 10
m1 = df['Values %'].ge(10).rolling(2).min().eq(1)
# give 2 consecutive 100
m2 = df['Values %'].eq(100).rolling(2).min().eq(1)

# set up grouper
group = (m2.shift()&~m2).cumsum()

# get values before (including) first m2 True
m3 = ((~m2).groupby(group, group_keys=False)
           .apply(lambda x: x.shift(fill_value=True).cummin())
     )

# get values between the first m1 True 
df['Flag'] = m1.groupby(group).cummax() & m3

输出:

index   Values %   Flag
0        0         0  False
1        1         5  False
2        2        11  False
3        3         9  False
4        4        14  False
5        5        18   True
6        6        30   True
7        7        54   True
8        8        73   True
9        9       100   True
10      10       100   True
11      11       100  False
12      12       100  False
13      13       100  False
14       0         0  False
15       1         5  False
16       2        11  False
17       3         9  False
18       4        14  False
19       5        18   True
20       6        30   True
21       7        54   True
22       8        73   True
23       9       100   True
24      10       100   True
25      11       100  False
26      12       100  False
27      13       100  False

中间体:

index   Values %   Flag     m1     m2  group     m3
0        0         0  False  False  False      0   True
1        1         5  False  False  False      0   True
2        2        11  False  False  False      0   True
3        3         9  False  False  False      0   True
4        4        14  False  False  False      0   True
5        5        18   True   True  False      0   True
6        6        30   True   True  False      0   True
7        7        54   True   True  False      0   True
8        8        73   True   True  False      0   True
9        9       100   True   True  False      0   True
10      10       100   True   True   True      0   True
11      11       100  False   True   True      0  False
12      12       100  False   True   True      0  False
13      13       100  False   True   True      0  False
14       0         0  False  False  False      1   True
15       1         5  False  False  False      1   True
16       2        11  False  False  False      1   True
17       3         9  False  False  False      1   True
18       4        14  False  False  False      1   True
19       5        18   True   True  False      1   True
20       6        30   True   True  False      1   True
21       7        54   True   True  False      1   True
22       8        73   True   True  False      1   True
23       9       100   True   True  False      1   True
24      10       100   True   True   True      1   True
25      11       100  False   True   True      1  False
26      12       100  False   True   True      1  False
27      13       100  False   True   True      1  False

相关问题