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