Pandas Split DataFrame с использованием индекса строки - PullRequest
0 голосов
/ 20 ноября 2018

Я хочу разделить фрейм данных по разному количеству строк, используя индекс строки.

Код ниже:

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

работает только для одинакового количества строк.

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 ]

0 голосов
/ 21 ноября 2018

Я думаю, что это то, что вам нужно:

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

Хотя понимание списка гораздо эффективнее цикла for, last_check необходим, если в вашем списке индексов нет шаблона.

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
0 голосов
/ 20 ноября 2018

Вы можете использовать понимание списка с небольшими изменениями в вашем списке, l, сначала.

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)]

Вывод:

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
0 голосов
/ 20 ноября 2018

Сделайте это:

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 голосов
/ 20 ноября 2018

Вы можете создать массив для индексации через 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 

Вместо определения новой переменной для каждого кадра данных, вы можете использовать словарь:

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 голосов
/ 20 ноября 2018

Я думаю, это то, что вы ищете.

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

Вывод:

   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

Другое решение:

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

Вывод:

   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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...