Je souhaite fractionner la trame de données par nombre de lignes irrégulier à l'aide de l'index de ligne.

Le code ci-dessous:

groups = df.groupby((np.arange(len(df.index))/l[1]).astype(int))

Ne fonctionne que pour un nombre uniforme de lignes.

df

a b c  
1 1 1  
2 2 2  
3 3 3  
4 4 4  
5 5 5  
6 6 6  
7 7 7  

l = [2, 5, 7]

df1  
1 1 1  
2 2 2  

df2  
3,3,3  
4,4,4  
5,5,5  

df3  
6,6,6  
7,7,7  

df4  
8,8,8
5
Pradeep Tummala 20 nov. 2018 à 13:51

5 réponses

Meilleure réponse

Vous pouvez utiliser la compréhension de liste avec quelques petites modifications sur votre liste, d'abord.

print(df)

   a  b  c
0  1  1  1
1  2  2  2
2  3  3  3
3  4  4  4
4  5  5  5
5  6  6  6
6  7  7  7
7  8  8  8


l = [2,5,7]
l_mod = [0] + l + [max(l)+1]

list_of_dfs = [df.iloc[l_mod[n]:l_mod[n+1]] for n in range(len(l_mod)-1)]

Production:

list_of_dfs[0]

   a  b  c
0  1  1  1
1  2  2  2

list_of_dfs[1]

   a  b  c
2  3  3  3
3  4  4  4
4  5  5  5

list_of_dfs[2]

   a  b  c
5  6  6  6
6  7  7  7

list_of_dfs[3]

   a  b  c
7  8  8  8
12
Scott Boston 20 nov. 2018 à 14:40

Je pense que c'est ce dont vous avez besoin:

df = pd.DataFrame({'a': np.arange(1, 8),
                  'b': np.arange(1, 8),
                  'c': np.arange(1, 8)})
df.head()
    a   b   c
0   1   1   1
1   2   2   2
2   3   3   3
3   4   4   4
4   5   5   5
5   6   6   6
6   7   7   7

last_check = 0
dfs = []
for ind in [2, 5, 7]:
    dfs.append(df.loc[last_check:ind-1])
    last_check = ind

Bien que la compréhension de la liste soit beaucoup plus efficace qu'une boucle for, le last_check est nécessaire si vous n'avez pas de modèle dans votre liste d'index.

dfs[0]

    a   b   c
0   1   1   1
1   2   2   2

dfs[2]

    a   b   c
5   6   6   6
6   7   7   7
2
Mohit Motwani 21 nov. 2018 à 09:37

Faites ceci:

l = [2,5,7]
d = dict()  # A dictionary to hold multiple dataframes

In [477]: for c,i in enumerate(l):
     ...:     if c == 0:
     ...:         index_list = df[df.a <= i].index
     ...:     else:
     ...:         index_list = df[(df.a > l[c-1]) & (df.a <= l[c])].index
     ...:     min_index = index_list[0]
     ...:     max_index = index_list[-1] + 1
     ...:     d[i] = df.iloc[min_index:max_index]
     ...:     


In [479]: for key in d.keys():
     ...:     print(d[key])
     ...:     
   a  b  c
0  1  1  1
1  2  2  2
   a  b  c
2  3  3  3
3  4  4  4
4  5  5  5
   a  b  c
5  6  6  6
6  7  7  7
0
Mayank Porwal 4 juil. 2019 à 04:44

Je pense que c'est ce que vous recherchez.,

l = [2, 5, 7]
dfs=[]
i=0
for val in l:
    if i==0:
        temp=df.iloc[:val]
        dfs.append(temp)
    elif i==len(l):
        temp=df.iloc[val]
        dfs.append(temp)        
    else:
        temp=df.iloc[l[i-1]:val]
        dfs.append(temp)
    i+=1

Production:

   a  b  c
0  1  1  1
1  2  2  2
   a  b  c
2  3  3  3
3  4  4  4
4  5  5  5
   a  b  c
5  6  6  6
6  7  7  7

Une autre solution:

l = [2, 5, 7]
t= np.arange(l[-1])
l.reverse()
for val in l:
    t[:val]=val
temp=pd.DataFrame(t)
temp=pd.concat([df,temp],axis=1)
for u,v in temp.groupby(0):
    print v

Production:

   a  b  c  0
0  1  1  1  2
1  2  2  2  2
   a  b  c  0
2  3  3  3  5
3  4  4  4  5
4  5  5  5  5
   a  b  c  0
5  6  6  6  7
6  7  7  7  7
1
Mohamed Thasin ah 20 nov. 2018 à 11:31

Vous pouvez créer un tableau à utiliser pour l'indexation via NumPy:

import pandas as pd, numpy as np

df = pd.DataFrame(np.arange(24).reshape((8, 3)), columns=list('abc'))

L = [2, 5, 7]
idx = np.cumsum(np.in1d(np.arange(len(df.index)), L))

for _, chunk in df.groupby(idx):
    print(chunk, '\n')

   a  b  c
0  0  1  2
1  3  4  5 

    a   b   c
2   6   7   8
3   9  10  11
4  12  13  14 

    a   b   c
5  15  16  17
6  18  19  20 

    a   b   c
7  21  22  23 

Au lieu de définir une nouvelle variable pour chaque trame de données, vous pouvez utiliser un dictionnaire:

d = dict(tuple(df.groupby(idx)))

print(d[1])  # print second groupby value

    a   b   c
2   6   7   8
3   9  10  11
4  12  13  14
0
jpp 20 nov. 2018 à 14:04