Разбить фрейм данных pandas на блоки на основе значений столбцов

#python #pandas #dataframe #pandas-groupby

#python #pandas #фрейм данных #pandas-groupby

Вопрос:

Я хочу разбить фрейм данных на блоки от одного истинного значения до следующего истинного значения:

данные Отметить
МОДЫ начинаются 12/12/2020 Верно
Некоторые данные False
Некоторые данные False
Начало модов 30/12/2020 Верно
Некоторые данные False
Некоторые данные False

Для

данные Отметить
МОДЫ начинаются 12/12/2020 Верно
Некоторые данные False
Некоторые данные False
данные Отметить
Начало модов 30/12/2020 Верно
Некоторые данные False
Некоторые данные False

Пожалуйста, помогите

Комментарии:

1. Какова логика разделения строк? Или вы хотите разделить каждые 3 строки в новом df?

2. Логика заключается в том, чтобы перемещать фрейм данных от одного True значения к следующему True значению

Ответ №1:

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

 df = pd.DataFrame({'data':['MODS start 12/12/202','Some data', 'Some data', 'MODS starts 30/12/2020', 'Some data', 'Some data'],
                  'flag':[True, False, False, True, False, False]})

df['grp'] = df['flag'].cumsum()

print(df)
 

Вывод:

                      data   flag  grp
0    MODS start 12/12/202   True    1
1               Some data  False    1
2               Some data  False    1
3  MODS starts 30/12/2020   True    2
4               Some data  False    2
5               Some data  False    2
 

Использование:

 df.query('grp == 1')

                   data   flag  grp
0  MODS start 12/12/202   True    1
1             Some data  False    1
2             Some data  False    1
 

и

 df.query('grp == 2')

                     data   flag  grp
3  MODS starts 30/12/2020   True    2
4               Some data  False    2
5               Some data  False    2
 

Комментарии:

1. Мило! Он также легко предоставляет переменную на случай, если OP захочет использовать groupby .

Ответ №2:

Вы можете использовать numpy.split :

 np.split(df, df.index[df.flag])[1:]
 

Здесь я использовал [1:] because numpy.split , чтобы также рассмотреть группы перед первым индексом, даже если он пустой.


Тем не менее, вы также можете использовать простое понимание списка:

 idx = df.index[df.flag].tolist()   [df.shape[0]]
[df.iloc[idx[i]:idx[i 1]] for i in range(len(idx)-1)]
 

Результат (оба подхода):

                     data   flag
0  MODS start 12/12/2020   True
1              Some data  False
2              Some data  False 

                    data   flag
3  MODS start 30/12/2020   True
4              Some data  False
5              Some data  False 
 

Комментарии:

1. В вашем первом ответе приятно то, что он разделяется динамически. Нам не нужно знать, сколько на самом деле существует групп, если у нас есть 50 миллионов данных и у вас нет цикла. Спасибо

2. Numpy — это круто! Рад помочь.

Ответ №3:

Получить список индексов строк с флагом = True

 true_idx = df[df['flag']==True].index
n = len(true_idx)
 

Выполните цикл по true_idx и создайте список фреймов данных от каждого истинного индекса к следующему

 new_dfs_list = [df.iloc[ true_idx[i]:true_idx[i 1], :] for i in range(n-1)]
 

добавьте последний df из последнего истинного индекса в хвост df

 new_dfs_list.append(df.iloc[ true_idx[n-1]:, :])
 

доступ к любому из ваших new_dfs по индексу

 print(new_dfs_list[-1])