Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何通过使用特定值分组行来拆分数据帧和创建子数据帧?_Python_Pandas - Fatal编程技术网

Python 如何通过使用特定值分组行来拆分数据帧和创建子数据帧?

Python 如何通过使用特定值分组行来拆分数据帧和创建子数据帧?,python,pandas,Python,Pandas,我有一个像贝娄一样的数据帧 date,value 2/10/19,34 2/11/19,34 2/12/19,34 2/13/19,34 2/14/19,34 2/15/19,34 2/16/19,34 2/17/19,0 2/18/19,0 2/19/19,0 2/20/19,22 2/21/19,22 2/22/19,22 2/23/19,22 2/24/19,0 2/25/19,0 2/26/19,0 2/27/19,0 2/28/19,1 3/1/19,2 3/2/19,2 3/3/19

我有一个像贝娄一样的数据帧

date,value
2/10/19,34
2/11/19,34
2/12/19,34
2/13/19,34
2/14/19,34
2/15/19,34
2/16/19,34
2/17/19,0
2/18/19,0
2/19/19,0
2/20/19,22
2/21/19,22
2/22/19,22
2/23/19,22
2/24/19,0
2/25/19,0
2/26/19,0
2/27/19,0
2/28/19,1
3/1/19,2
3/2/19,2
3/3/19,1
3/4/19,0
3/5/19,0
3/6/19,0
3/7/19,3
3/8/19,3
3/9/19,3
3/10/19,0
在每个间隔数据帧都有零值之后,我希望以这样的方式对行进行分组:如果零连续出现两次以上,它应该创建一个子数据帧并保存一个文件

Output:


df1 
    2/17/19,0
    2/18/19,0
    2/19/19,0
df2
    2/24/19,0
    2/25/19,0
    2/26/19,0
    2/27/19,0
df3
    3/4/19,0
    3/5/19,0
    3/6/19,0
我尝试了很多方法,但都失败了


多谢各位

您可以尝试使用滚动:

def merge_intervals(intervals):
    sorted_intervals = sorted(intervals, key=lambda x: x[0])
    interval_index = 0
    #print(sorted_intervals)
    for  i in sorted_intervals:

        if i[0] > sorted_intervals[interval_index][1]:
            interval_index += 1
            sorted_intervals[interval_index] = i
        else:
            sorted_intervals[interval_index] = [sorted_intervals[interval_index][0], i[1]]
    #print(sorted_intervals)
    return sorted_intervals[:interval_index+1]

end_ids = df[df['value'].rolling(3).apply(lambda x: (x==0).all())==1].index

start_ids = end_ids-3

intervals = merge_intervals([*zip(starts_ids, end_ids)])

for i,interval in enumerate(intervals):
    df[interval[0]+1:interval[1]+1].to_csv('df_' + str(i) + '.csv')

虽然不是最漂亮的代码,但它很有效,这里找到了merge函数:

查找值等于零的位置,并取长度为3的滚动和。找出滚动和等于3的位置。结果将滞后2个空格,因此我们采用结果的逻辑<代码>或,以及结果的-1移位和-2移位版本

mask = df['value'].eq(0).rolling(3).sum().eq(3)
mask |= mask.shift(-2) | mask.shift(-1)
为了得到组,我取逻辑否定的累积和。这将为每个非零值递增,并在零处停滞。但是,每组零将是不同的。在我使用
groupby
时,这并不重要,因为我将使用初始
mask
只查看首先满足条件的行

但是,结果组将是一组不连续的整数。因为我不喜欢这样,我使用了
factorize
为这些组提供从零开始的唯一整数值

grp_masked = (~mask).cumsum()[mask].factorize()[0]
g = df[mask].groupby(grp_masked)

保存文件
创建字典
细节 这显示了原始数据帧以及显示我们计算的一些内容的附加列

group_series = pd.Series(
    grp_masked, df.index[mask], pd.Int64Dtype()
)

df_ = df.assign(
    EqZero=df['value'].eq(0),
    Roll2=df['value'].eq(0).rolling(3).sum(),
    Is3=df['value'].eq(0).rolling(3).sum().eq(3),
    Shift=lambda d: d.Is3.shift(-2) | d.Is3.shift(-1),
    Mask=mask,
    PreGrp=(~mask).cumsum(),
    Grp=group_series
)

df_
日期值EqZero Roll2为3移位掩码PreGrp Grp
0 2/10/19 34假南假假假假1
1919年12月11日0真NaN假False假2
2 2/12/19 0正确2.0错误3
3 2/13/19 34假2.0假假4
4 2/14/19 34假1.0假5
5 19年2月15日34假0.0假假6
6 2/16/19 34假0.0假7
7 2/17/19 0真1.0假真7 0
8 2/18/19 0真2.0假真7 0
9 2/19/19 0真3.0真假真7 0
10 2/20/19 22假2.0假8
2011年2月21日22假1.0假9
12 2/22/19 22假0.0假假10
13 2/23/19 22假0.0假假11
14 2/24/19 0真1.0假真11 1
15 2/25/19 0真2.0假真11 1
19年2月26日0真实3.0真实11 1
17 2/27/19 0正确3.0正确错误11 1
19年2月28日1假2.0假12
19 3/1/19 2假1.0假假13
20 3/2/19 2假0.0假假14
21 3/3/19 1假0.0假假15
22 3/4/19 0真1.0假真15 2
23 3/5/19 0正确2.0错误正确15 2
24 3/6/19 0真3.0真假真15 2
25 3/7/19 3假2.0假假16
26 19年3月8日3假1.0假17
27 3/9/19 3假0.0假假18
28 19年3月10日0真1.0假假19

我认为代码已经足够接近了,但如果我正确理解了“滚动(3)”会产生一些麻烦,并且只生成3行的数据帧,并且在不同的数据帧中有相同的行。我必须理解此代码并进行相应修改。虽然这很有帮助。谢谢。对不起,我没有看到你想要>=3,我修正了代码以这种方式工作。嘿,这是我花了几个小时的时间尝试的。谢谢。你想只保留带零的行吗?非常精确的代码和很好的解释谢谢分享。
df_dict = {grp: d for grp, d in g}
group_series = pd.Series(
    grp_masked, df.index[mask], pd.Int64Dtype()
)

df_ = df.assign(
    EqZero=df['value'].eq(0),
    Roll2=df['value'].eq(0).rolling(3).sum(),
    Is3=df['value'].eq(0).rolling(3).sum().eq(3),
    Shift=lambda d: d.Is3.shift(-2) | d.Is3.shift(-1),
    Mask=mask,
    PreGrp=(~mask).cumsum(),
    Grp=group_series
)
df_

       date  value  EqZero  Roll2    Is3  Shift   Mask  PreGrp   Grp
0   2/10/19     34   False    NaN  False  False  False       1  <NA>
1   2/11/19      0    True    NaN  False  False  False       2  <NA>
2   2/12/19      0    True    2.0  False  False  False       3  <NA>
3   2/13/19     34   False    2.0  False  False  False       4  <NA>
4   2/14/19     34   False    1.0  False  False  False       5  <NA>
5   2/15/19     34   False    0.0  False  False  False       6  <NA>
6   2/16/19     34   False    0.0  False  False  False       7  <NA>
7   2/17/19      0    True    1.0  False   True   True       7     0
8   2/18/19      0    True    2.0  False   True   True       7     0
9   2/19/19      0    True    3.0   True  False   True       7     0
10  2/20/19     22   False    2.0  False  False  False       8  <NA>
11  2/21/19     22   False    1.0  False  False  False       9  <NA>
12  2/22/19     22   False    0.0  False  False  False      10  <NA>
13  2/23/19     22   False    0.0  False  False  False      11  <NA>
14  2/24/19      0    True    1.0  False   True   True      11     1
15  2/25/19      0    True    2.0  False   True   True      11     1
16  2/26/19      0    True    3.0   True   True   True      11     1
17  2/27/19      0    True    3.0   True  False   True      11     1
18  2/28/19      1   False    2.0  False  False  False      12  <NA>
19   3/1/19      2   False    1.0  False  False  False      13  <NA>
20   3/2/19      2   False    0.0  False  False  False      14  <NA>
21   3/3/19      1   False    0.0  False  False  False      15  <NA>
22   3/4/19      0    True    1.0  False   True   True      15     2
23   3/5/19      0    True    2.0  False   True   True      15     2
24   3/6/19      0    True    3.0   True  False   True      15     2
25   3/7/19      3   False    2.0  False  False  False      16  <NA>
26   3/8/19      3   False    1.0  False  False  False      17  <NA>
27   3/9/19      3   False    0.0  False  False  False      18  <NA>
28  3/10/19      0    True    1.0  False  False  False      19  <NA>