Katakanlah saya memiliki kerangka data berikut:

import pandas as pd
import numpy as np

df = pd.DataFrame({'dif_seq': [np.nan, 1, 1, 1, 1, -23, 1, 1, 1, -4, 1, 1], 'data': range(12)})

df
Out[75]: 
    dif_seq  data
0       NaN     0
1       1.0     1
2       1.0     2
3       1.0     3
4       1.0     4
5     -23.0     5
6       1.0     6
7       1.0     7
8       1.0     8
9      -4.0     9
10      1.0    10
11      1.0    11

Saya ingin membagi df ke dalam daftar kerangka data berdasarkan nilai dalam df['dif_seq'] sebagai berikut (semua nilai negatif atau np.nan menandakan awal dari df baru):

    dif_seq  data
0       NaN     0
1       1.0     1
2       1.0     2
3       1.0     3
4       1.0     4

    dif_seq  data
5     -23.0     5
6       1.0     6
7       1.0     7
8       1.0     8

    dif_seq  data
9      -4.0     9
10      1.0    10
11      1.0    11

Apa cara terbaik untuk masalah ini? Saya memiliki masalah analog dengan kumpulan data yang sangat besar. Jadi meskipun ini adalah contoh kecil, apa rute tercepat yang harus ditempuh?

2
Andrea 23 April 2021, 21:20

3 jawaban

Jawaban Terbaik

Saya ingin membagi df menjadi daftar kerangka data

Anda dapat mencoba dengan jumlah kumulatif bersyarat dan np.split:

c = df['dif_seq'].lt(0)|df['dif_seq'].isna()
#c= ~df.dif_seq.ge(0) : courtesy @MustafaAydın
s = c.cumsum()
l = np.split(df,np.where(np.diff(s)>0)[0]+1)
#or for a dictionary: dict(iter(df.groupby(s)))

>>l

[   dif_seq  data
 0      NaN     0
 1      1.0     1
 2      1.0     2
 3      1.0     3
 4      1.0     4,
    dif_seq  data
 5    -23.0     5
 6      1.0     6
 7      1.0     7
 8      1.0     8,
     dif_seq  data
 9      -4.0     9
 10      1.0    10
 11      1.0    11]
5
anky 23 April 2021, 18:37

Buat rangkaian daripada menetapkan potongan dan kemudian menggunakannya sebagai topeng.

df = pd.DataFrame({'dif_seq': [np.nan, 1, 1, 1, 1, -23, 1, 1, 1, -4, 1, 1], 'data': range(12)})

s = (df["dif_seq"].isna() | df["dif_seq"].lt(0)).cumsum()

split = {f"df{i}":df.loc[s.eq(i)] for i in s.unique()}

split

Keluaran

{'df1':    dif_seq  data
 0      NaN     0
 1      1.0     1
 2      1.0     2
 3      1.0     3
 4      1.0     4,
 'df2':    dif_seq  data
 5    -23.0     5
 6      1.0     6
 7      1.0     7
 8      1.0     8,
 'df3':     dif_seq  data
 9      -4.0     9
 10      1.0    10
 11      1.0    11}
1
Rob Raymond 23 April 2021, 18:29

Buat kunci sub-grup dengan diff dan cumsum

s = df['dif_seq'].diff()
s = (s.notnull()& s.ne(0)).cumsum()
s
0     0
1     0
2     0
3     0
4     0
5     1
6     2
7     2
8     2
9     3
10    4
11    4
Name: dif_seq, dtype: int32
d = {x : y for x , y in df.groupby(s)}
1
BENY 23 April 2021, 18:24