将数据拆分为连续组

时间:2018-05-10 13:38:32

标签: python pandas dataframe pandas-groupby

我对编码很新,所以请耐心等待。我有一个带有连续序列的正值或负值的pandas df或0。

    df = 
    x    y
0   -5   25
1   -7   32
2   -3   33
3    0   22
4    1   16
5    6   10
6    3   36
7    0   22
8    0   55
9   -10  24
10  -9   32 
11  -8   5
12  11   4
13  17   9
14  13   88
15   0   14
16   0   12
17   0   0
18   0   10
19   0   96
20  -1   492
21  -9   -440
22  -3   34

我想像这样分解这些数据:

data1 = [-5 -7 -3 0]
data2 = [1 6 3 0 0]
data3 = [-10 -9 -8]
data4 = [11 17 13 0 0 0 0 0]
data5 = [-1 -9 -3]

其中值0或任意数量的0一起放置在它之前的值和仅为负或正的集合中。

非常感谢任何正确方向的帮助或指针。

2 个答案:

答案 0 :(得分:3)

我将其视为pandas Series

#A=pd.Series(lst)
idx=A.index
A=A.loc[A!=0].to_frame('Val')
A['Group']=A.ge(0).astype(int).diff().ne(0).cumsum()
A=A.reindex(idx)
A.Val=A.Val.fillna(0).astype(int)
A.Group=A.Group.ffill()
A.groupby('Group').Val.apply(list).tolist()


[[-5, -7, -3, 0],
 [1, 6, 3, 0, 0],
 [-10, -9, -8],
 [11, 17, 13, 0, 0, 0, 0, 0],
 [-1, -9, -3]]

关于数据框A

A
Out[23]: 
    Val  Group
0    -5    1.0
1    -7    1.0
2    -3    1.0
3     0    1.0
4     1    2.0
5     6    2.0
6     3    2.0
7     0    2.0
8     0    2.0
9   -10    3.0
10   -9    3.0
11   -8    3.0
12   11    4.0
13   17    4.0
14   13    4.0
15    0    4.0
16    0    4.0
17    0    4.0
18    0    4.0
19    0    4.0
20   -1    5.0
21   -9    5.0
22   -3    5.0

答案 1 :(得分:2)

np.splitnp.flatnonzero

这里的要点是创建一个布尔数组,用于标识值在负,正或零之间的变化,同时也不为零。这将找到小组的开头。

a = np.sign(df.x.values)
b = np.append(False, a[:-1] != a[1:])
splits_dict = dict(enumerate(np.split(df, np.flatnonzero(a.astype(bool) & b))))

pd.concat(splits_dict)

       x    y
0 0   -5   25
  1   -7   32
  2   -3   33
  3    0   22
1 4    1   16
  5    6   10
  6    3   36
  7    0   22
  8    0   55
2 9  -10   24
  10  -9   32
  11  -8    5
3 12  11    4
  13  17    9
  14  13   88
  15   0   14
  16   0   12
  17   0    0
  18   0   10
  19   0   96
4 20  -1  492
  21  -9 -440
  22  -3   34

set_index

如果打算将信息嵌入到数据框中,我们可以做到:

a = np.sign(df.x.values)
b = np.append(False, a[:-1] != a[1:])
c = (a.astype(bool) & b).cumsum()

df.set_index([c, df.index])

       x    y
0 0   -5   25
  1   -7   32
  2   -3   33
  3    0   22
1 4    1   16
  5    6   10
  6    3   36
  7    0   22
  8    0   55
2 9  -10   24
  10  -9   32
  11  -8    5
3 12  11    4
  13  17    9
  14  13   88
  15   0   14
  16   0   12
  17   0    0
  18   0   10
  19   0   96
4 20  -1  492
  21  -9 -440
  22  -3   34