Estou tentando cruzar dois bancos de dados enormes. Uma tem 15 milhões de linhas e outra uns 25 milhões. As duas são dataframes em Pandas. No momento, estou dividindo uma das bases (a com 15 milhões) em bases menores (com cerca de 10000 linhas (isso é necessário para a pauta) e depois disso cruzando com a base maior.
Esse cruzamento é feito primeiro transformando as colunas que eu quero cruzar em listas. Depois, cruzo as duas listas com o seguinte comando:
Como é de se imaginar, o processo demora MUITO tempo. Queria a ajuda de vocês para tentar descobrir um jeito que demore menos. Alguém tem alguma ideia de como melhorar esse processo?
Olá @lucasmarchesini
Este exemplo de script lê os arquivos de sócios que a Receita Federal divulga periodicamente, também com milhões de linhas
Basicamente eu leio o arquivo com Python separando ele em chunks de 100000 e com isso faço filtros e cruzamentos necessários. Roda muito rápido. Veja se serve ou coloque seu código aqui para vermos
#Pega todas as cidades e o código dela e salva em uma lista de listas. O primeiro elemento de cada lista é o código e o segundo o nome
cidades = []
with open(‘cidades.csv’) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=’,’)
for row in csv_reader:
cidades.append(row)
#Abre o dataset grande
#dados_1= pd.read_csv(“dados_1”)
#Guarda os dados em uma lista #nomes_dados_1 = list(dados_1[“nome”])
#Cria os objetos para fazer o loop entre os diferentes documentos
meses = [“01”, “02”, “03”, “04”, “05”, “06”, “07”, “08”, “09”] #Faz os loops para fazer os cruzamentos
for mes in meses:
df = pd.read_csv(“2019” + mes + “.csv”, encoding=“iso-8859-1”, sep=";")
for cidade in cidades: #Mantém só o município a ser investigado
cid = df[df[“CÓDIGO MUNICÍPIO”] == int(cidade[0])]
#Transforma nomes em uma lista
lista_nomes = list(cid["NOME"])
#Pega os nomes iguais nos dois bancos de dados
nomes_iguais = list(set(nomes_dados_1 & set(lista_nomes))
O que você precisa comparar são nomes de cidades, certo?
Primeiro, toma cuidado com a acentuação para comparar - tem jeito de retirar - e também é bom transformar tudo em upper
Depois, não sei se comparar listas é o mais seguro num caso com vários arquivos. Talvez você possa transformar tudo em dataframe
Imaginando que você quer comparar dois dataframes:
# Cria um chunk de 100 mil para o arquivo muito grande, aqui o dados_1
TextFileReader = pd.read_csv('dados_1',\
chunksize=100000,\
sep=',',\
names=['nome_cidade'],\
dtype={'nome_cidade': str})
# imagine que df_compara é um dataframe com a coluna 'nome_cidade'
# e que o arquivo dados_1 também tem uma coluna com o mesmo nome (poderia ser outro, é só mudar)
conta = 0
for df_arquivo in TextFileReader:
# merge compara e une dois dataframes a partir de valores iguais
nomes_iguais = pd.merge(df_compara, df_arquivo, left_on='nome_cidade', right_on='nome_cidade')
# Testa se o merge não é vazio
if nomes_iguais.empty is False:
# Testa se é a primeira vez
if conta == 0:
df_final = nomes_iguais
# Na segunda vez faz append no dataframe final
else:
df_final = df_final.append(nomes_iguais)
conta = conta + 1
E também para esclarecer dúvidas é sempre bom indicar como é cada arquivo que você possui: qual o nome do arquivo, quais as colunas têm, são de qual tipo… - se quiser detalha isso que tento mandar um código completo
Se for para cruzar cidades, veja se não vale a pena transformá-las em category em vez de trabalhar com string. Isso pode reduzir o consumo de memória e tornar o processamento mais rápido. Escrevi sobre isso neste post (desculpa o merchan, mas achei válido compartilhar).