У меня есть большая база данных, которую мне нужно разделить на разные сегменты (разные «действительны до даты»), а затем поместить каждый из сегментов в книгу Excel. Каждый из сегментов также должен иметь свою таблицу Excel.
Пример Df:
A valid until C D
Date
01/08/2023 Tesouro Educa+ 15/12/2030 5,06 5,18
02/08/2023 Tesouro Educa+ 15/12/2030 5,05 5,17
03/08/2023 Tesouro Educa+ 15/12/2030 5,02 5,14
04/08/2023 Tesouro IPCA+ 15/12/2030 5,02 5,14
07/08/2023 Tesouro IPCA+ 15/12/2030 4,98 5,10
...
01/08/2023 Tesouro Selic 15/12/2031 5,05 5,17
02/08/2023 Tesouro Selic 15/12/2031 5,03 5,15
03/08/2023 Tesouro Educa+ 15/12/2031 5,00 5,12
04/08/2023 Tesouro Educa+ 15/12/2031 5,02 5,14
07/08/2023 Tesouro Educa+ 15/12/2031 4,99 5,11
Что я пробовал:
df = pd.read_csv(r'PATH', sep=';')
df.sort_values(by=['valid until','Date'], key=lambda x: np.argsort(natsorted(dados['Date'])))
valid_until_list=dados['valid until'].unique()
for i in valid_until_list:
df2=df[(df['Date']==f'{i}')]
df2=df2.set_index(['Data Base'])
with pd.ExcelWriter(r'NEW_PATH',engine='openpyxl', if_sheet_exists='replace', mode='a') as writer:
i=i.replace('/','_')
# Here i tried changing the name of the worksheets:
sheet_title=''
if df2['A']=='Tesouro IPCA+ com Juros Semestrais':
sheet_title='IPCA+ Juros'
elif nova_df2['A']=='Tesouro IPCA+':
sheet_title='IPCA+'
else:
sheet_title=''
df2.to_excel(writer, sheet_name=f'{sheet_title}_{i}')`
Код работал, пока я не попытался изменить заголовок листа, теперь показывает это: ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Я здесь, чтобы спросить 2 вещи. Мой df довольно большой (145712 строк), поэтому выполнение кода занимает слишком много времени. Есть ли более быстрый способ сделать это, возможно, без использования циклов for и if? Второй вопрос: как мне исправить эту ошибку в заголовке? Это не обязательно, но мне ооочень облегчит жизнь :))
Вы можете использовать groupby
, чтобы формировать DF и записывать их непосредственно на листы; код ниже определяет группы по принципу «действителен до», а затем сортирует каждую группу (т. е. суб-DF) в соответствии со столбцом Date
.
groupings = df.groupby('valid until')
count = 1
with pd.ExcelWriter("test.xlsx", mode = 'w') as writer:
for g in groupings:
sheetname = 'sheet'+str(count)
g[1].sort_values(by = 'Date').to_excel(writer, sheet_name=sheetname, index=False)
count += 1
Это дает лист1, лист2 и т. д., но вы можете изменить формирование имени листа по мере необходимости. «Действительно до» каждого DF указано g[0]
в приведенном выше коде, если это полезно.
Если требуется сформировать группы (и, следовательно, суб-DF), используя как «действителен до», так и «Дата», тогда оператор группировки будет изменен на groupings = df.groupby(['valid until', 'Date'])
, а выражение сортировки затем будет исключено из оператора в цикле for.
Тот же общий принцип можно использовать для формирования суб-DF с использованием любой комбинации столбцов.
Вы имеете в виду сортировку порядка по Date
внутри «сегмента», определенного только valid until
, или использовать оба valid until
и Date
для определения «сегментов» для отдельных DF? См. отредактированный ответ, который охватывает оба этих подхода. Если это не то, что вы хотите, уточните, и я скорректирую ответ. Лучший способ — использовать groupby
для формирования групп, которые настраиваются по вашему желанию; это предпочтительнее использования цикла для формирования суб-DF.
Спасибо за предложение. Его необходимо будет отсортировать по дате (когда оно было опубликовано) и по сроку действия до (когда истечет срок проверки).