Python 熊猫:标记连续值

Python 熊猫:标记连续值,python,pandas,Python,Pandas,我有一个熊猫系列的表格[0,1,0,1,1,1,0,0,1,1,0,1,0,0,1]。 0: indicates economic increase. 1: indicates economic decline. 经济衰退的信号是连续两次下降(1) 经济衰退结束的信号是连续两次增长(0) 在上面的数据集中,我有两次衰退,从指数3开始,从指数5结束,从指数8开始,从指数11结束 我对如何对待熊猫感到困惑。我想确定衰退开始和结束的指数。任何协助都将不胜感激 下面是我在解决方案方面的python尝试

我有一个熊猫系列的表格
[0,1,0,1,1,1,0,0,1,1,0,1,0,0,1]。

0: indicates economic increase.
1: indicates economic decline.
经济衰退的信号是连续两次下降(1)

经济衰退结束的信号是连续两次增长(0)

在上面的数据集中,我有两次衰退,从指数3开始,从指数5结束,从指数8开始,从指数11结束

我对如何对待熊猫感到困惑。我想确定衰退开始和结束的指数。任何协助都将不胜感激

下面是我在解决方案方面的python尝试

np_decline =  np.array([0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0 , 0 , 1])
recession_start_flag = 0
recession_end_flag = 0
recession_start = []
recession_end = []

for i in range(len(np_decline) - 1):
    if recession_start_flag == 0 and np_decline[i] == 1 and np_decline[i + 1] == 1:
        recession_start.append(i)
        recession_start_flag = 1
    if recession_start_flag == 1 and np_decline[i] == 0 and np_decline[i + 1] == 0:
        recession_end.append(i - 1)
        recession_start_flag = 0

print(recession_start)
print(recession_end)
这是一种更加以熊猫为中心的方法吗? Leon

您可以使用:

使用
rolling(2)

我减去
.5
,因此当衰退开始时
滚动
和为
1
,当衰退停止时为
-1

s2 = s.sub(.5).rolling(2).sum()
由于
1
-1
的计算结果均为
True
,因此我可以将滚动信号屏蔽为仅开始和停止以及
ffill
。使用
gt(0)
获取正值或负值时的真值


使用
shift
类似的方法,但将结果写入单个布尔列:

# Boolean indexers for recession start and stops.
rec_start = (df['signal'] == 1) & (df['signal'].shift(-1) == 1)
rec_end = (df['signal'] == 0) & (df['signal'].shift(-1) == 0)

# Mark the recession start/stops as True/False.
df.loc[rec_start, 'recession'] = True
df.loc[rec_end, 'recession'] = False

# Forward fill the recession column with the last known Boolean.
# Fill any NaN's as False (i.e. locations before the first start/stop).
df['recession'] = df['recession'].ffill().fillna(False)
结果输出:

    signal recession
0        0     False
1        1     False
2        0     False
3        1      True
4        1      True
5        1      True
6        0     False
7        0     False
8        1      True
9        1      True
10       0      True
11       1      True
12       0     False
13       0     False
14       1     False

运行1的开始满足条件

x_prev = x.shift(1)
x_next = x.shift(-1)
((x_prev != 1) & (x == 1) & (x_next == 1))
((x == 1) & (x_next == 0) & (x_next2 == 0))
也就是说,运行开始时的值为1,前一个值不是1,下一个值为1。类似地,运行结束时满足该条件

x_prev = x.shift(1)
x_next = x.shift(-1)
((x_prev != 1) & (x == 1) & (x_next == 1))
((x == 1) & (x_next == 0) & (x_next2 == 0))
因为运行结束时的值为1,接下来的两个值为0。 我们可以使用
np.flatnonzero
找到这些条件为真的索引:

import numpy as np
import pandas as pd

x = pd.Series([0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0 , 0 , 1])
x_prev = x.shift(1)
x_next = x.shift(-1)
x_next2 = x.shift(-2)
df = pd.DataFrame(
    dict(start = np.flatnonzero((x_prev != 1) & (x == 1) & (x_next == 1)),
         end = np.flatnonzero((x == 1) & (x_next == 0) & (x_next2 == 0))))
print(df[['start', 'end']])
屈服

   start  end
0      3    5
1      8   11

您可以使用scipy.signal.find_peaks解决此问题

    from scipy.signal import find_peaks

    np_decline =  np.array([0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0 , 0 , 1])
    peaks = find_peaks(np_decline,width=2)
    recession_start_loc =  peaks[1]['left_bases'][0]

也许只是用0来
.fillna
使它整洁。Hi@piRSquared。我怎样才能修改你们在衰退开始和衰退结束两栏中所做的工作。如果衰退开始是真的,那么衰退开始是假的。当然,如果衰退结束是真的,那么衰退结束是假的。
    from scipy.signal import find_peaks

    np_decline =  np.array([0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0 , 0 , 1])
    peaks = find_peaks(np_decline,width=2)
    recession_start_loc =  peaks[1]['left_bases'][0]