Eu tenho uma grande quantidade de dados em uma coleção no mongodb que preciso analisar. Como faço para importar esses dados para o pandas?
Eu sou novo em pandas e entorpecido.
EDITAR: A coleção mongodb contém valores de sensor marcados com data e hora. Os valores do sensor são do tipo de dados flutuante.
Dados de amostra:
{
"_cls" : "SensorReport",
"_id" : ObjectId("515a963b78f6a035d9fa531b"),
"_types" : [
"SensorReport"
],
"Readings" : [
{
"a" : 0.958069536790466,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:26:35.297Z"),
"b" : 6.296118156595,
"_cls" : "Reading"
},
{
"a" : 0.95574014778624,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:27:09.963Z"),
"b" : 6.29651468650064,
"_cls" : "Reading"
},
{
"a" : 0.953648289182713,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:27:37.545Z"),
"b" : 7.29679823731148,
"_cls" : "Reading"
},
{
"a" : 0.955931884300997,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:28:21.369Z"),
"b" : 6.29642922525632,
"_cls" : "Reading"
},
{
"a" : 0.95821381,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:41:20.801Z"),
"b" : 7.28956613,
"_cls" : "Reading"
},
{
"a" : 4.95821335,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:41:36.931Z"),
"b" : 6.28956574,
"_cls" : "Reading"
},
{
"a" : 9.95821341,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:42:09.971Z"),
"b" : 0.28956488,
"_cls" : "Reading"
},
{
"a" : 1.95667927,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:43:55.463Z"),
"b" : 0.29115237,
"_cls" : "Reading"
}
],
"latestReportTime" : ISODate("2013-04-02T08:43:55.463Z"),
"sensorName" : "56847890-0",
"reportCount" : 8
}
mongo_doc.data_frame = my_pandas_df
Respostas:
pymongo
pode lhe dar uma mão, a seguir estão alguns códigos que estou usando:fonte
list()
interior édf = pd.DataFrame(list(cursor))
avaliado como uma lista ou gerador, para manter a refrigeração da CPU. Se você tiver zilhão e um itens de dados, e as próximas linhas os tivessem particionado razoavelmente, nível de detalhe e cortado, todo o shmegegge ainda é seguro para entrar. Legal.df = pd.DataFrame(list(cursor))
. A consulta de banco de dados puro é muito mais rápida. Podemos mudar olist
elenco para outra coisa?Você pode carregar seus dados mongodb para pandas DataFrame usando este código. Funciona para mim. Esperançosamente para você também.
fonte
Monary
faz exatamente isso e é super rápido . ( outro link )Veja este post legal que inclui um tutorial rápido e alguns horários.
fonte
client = Monary(host, 27017, database="db_tmp") columns = ["col1", "col2"] data_type = ["int64", "int64"] arrays = client.query("db_tmp", "coll", {}, columns, data_type)
Para50000
registros leva cerca200s
.De acordo com o PEP, simples é melhor do que complicado:
Você pode incluir condições como faria ao trabalhar com o banco de dados mongoDB regular ou até mesmo usar find_one () para obter apenas um elemento do banco de dados, etc.
e voila!
fonte
fonte
Para lidar com dados fora do núcleo (não cabendo na RAM) de forma eficiente (ou seja, com execução paralela), você pode tentar o ecossistema Python Blaze : Blaze / Dask / Odo.
Blaze (e Odo ) tem funções prontas para lidar com o MongoDB.
Alguns artigos úteis para começar:
E um artigo que mostra que coisas incríveis são possíveis com a pilha Blaze: Analisando 1,7 bilhões de comentários do Reddit com Blaze e Impala (essencialmente, consultar 975 Gb de comentários do Reddit em segundos).
PS Não sou afiliado a nenhuma dessas tecnologias.
fonte
Outra opção que achei muito útil é:
desta forma, você obtém o desdobramento de documentos mongodb aninhados gratuitamente.
fonte
TypeError: data argument can't be an iterator
3.6.7
usando pandas0.24.2
. Emdf = json_normalize(list(cursor))
vez disso, você pode tentar ?Usando
irá consumir muita memória se o resultado do iterador / gerador for grande
melhor gerar pequenos pedaços e concat no final
fonte
http://docs.mongodb.org/manual/reference/mongoexport
exportar para csv e usar
read_csv
ou JSON e usarDataFrame.from_records()
fonte
DataFrame.from_records()
.Seguindo esta ótima resposta esperandokuo , gostaria de adicionar a possibilidade de fazer isso usando chunksize em linha com .read_sql () e .read_csv () . Eu amplio a resposta de Deu Leung evitando ir um por um cada 'registro' do 'iterador' / 'cursor'. Vou pedir emprestada a função read_mongo anterior .
fonte
Uma abordagem semelhante, como Rafael Valero, waitingkuo e Deu Leung usando paginação :
fonte
Você pode conseguir o que deseja com pdmongo em três linhas:
Se seus dados forem muito grandes, você pode fazer uma consulta agregada primeiro, filtrando os dados que não deseja e, em seguida, mapeá-los para as colunas desejadas.
Aqui está um exemplo de mapeamento
Readings.a
para colunaa
e filtragem porreportCount
coluna:read_mongo
aceita os mesmos argumentos do agregado pymongofonte