使用 pandas 将新字段(列)插入到 mongoDB
Inserting new fields(columns) to mongoDB with pandas
我在 MongoDB 中有一个现有数据,其中主键设置在 'date' 上,其中有几个字段。
并且我想将一个带有新字段(列)的新 pandas 数据框插入到 MongoDB 中的现有数据中,加入两个数据框上都存在的 'date' 字段.
例如,假设这是我 MongoDB 中的数据框 A(我在从 MongoDB 调用数据时使用 'date' 字段设置索引)
这是我要插入到 MongoDB
的新数据框 B
这是带有新字段的最终数据帧 C('std_50_3000window'、'std_50_300window'、'std_50_500window' 添加到 'date' 索引),我希望它具有我的 MongoDB.
有什么办法吗?? (也许用 insert_many 方法?)
你需要的方法是update_one()
和upsert=True
循环;您不能使用 insert_many()
有两个原因;首先,您并不总是插入;有时你在更新;其次 update_many()
(和 insert_many()
)仅适用于单个过滤器;在您的情况下,每个过滤器都不同,因为每个更新都涉及不同的时间。
这是一种通用解决方案,它将按照您需要的方式组合数据帧(df_a
、df_b
在这种情况下 - 您可以拥有任意数量的数据帧。它使用 iterrows 获取数据框的每一行,过滤日期,并将值设置为数据框中的值。 $set
运算符将覆盖值(如果它们已经存在)并设置它们(如果未设置)。 upsert=True
如果日期不匹配,将执行插入。
for df in [df_a, df_b]:
for _, row in df.iterrows():
db.mycollection.update_one({'date': row.get('date')}, {'$set': row.to_dict()}, upsert=True)
完整的示例:
from pymongo import MongoClient
from pprint import pprint
import datetime
import pandas as pd
# Sample data setup
db = MongoClient()['mydatabase']
data_a = [[datetime.datetime(2017, 5, 19, 21, 20), 96, 8, 98],
[datetime.datetime(2017, 5, 19, 21, 21), 95, 8, 97],
[datetime.datetime(2017, 5, 19, 21, 22), 95, 8, 97]]
df_a = pd.DataFrame(data_a, columns=['date', 'std_500_1000window', 'std_50_100window', 'std_50_2000window'])
data_b = [[datetime.datetime(2017, 5, 19, 21, 20), 98, 9, 10],
[datetime.datetime(2017, 5, 19, 21, 21), 98, 9, 10],
[datetime.datetime(2017, 5, 19, 21, 22), 98, 9, 10]]
df_b = pd.DataFrame(data_b, columns=['date', 'std_50_3000window', 'std_50_300window', 'std_50_500window'])
# Perform the upserts
for df in [df_a, df_b]:
for _, row in df.iterrows():
db.mycollection.update_one({'date': row.get('date')}, {'$set': row.to_dict()}, upsert=True)
# Print the results
for record in db.mycollection.find():
pprint(record)
结果:
{'_id': ObjectId('5f0ae909df5531ac655ce528'),
'date': datetime.datetime(2017, 5, 19, 21, 20),
'std_500_1000window': 96,
'std_50_100window': 8,
'std_50_2000window': 98,
'std_50_3000window': 98,
'std_50_300window': 9,
'std_50_500window': 10}
{'_id': ObjectId('5f0ae909df5531ac655ce52a'),
'date': datetime.datetime(2017, 5, 19, 21, 21),
'std_500_1000window': 95,
'std_50_100window': 8,
'std_50_2000window': 97,
'std_50_3000window': 98,
'std_50_300window': 9,
'std_50_500window': 10}
{'_id': ObjectId('5f0ae909df5531ac655ce52c'),
'date': datetime.datetime(2017, 5, 19, 21, 22),
'std_500_1000window': 95,
'std_50_100window': 8,
'std_50_2000window': 97,
'std_50_3000window': 98,
'std_50_300window': 9,
'std_50_500window': 10}
我在 MongoDB 中有一个现有数据,其中主键设置在 'date' 上,其中有几个字段。
并且我想将一个带有新字段(列)的新 pandas 数据框插入到 MongoDB 中的现有数据中,加入两个数据框上都存在的 'date' 字段.
例如,假设这是我 MongoDB 中的数据框 A(我在从 MongoDB 调用数据时使用 'date' 字段设置索引)
这是我要插入到 MongoDB
的新数据框 B这是带有新字段的最终数据帧 C('std_50_3000window'、'std_50_300window'、'std_50_500window' 添加到 'date' 索引),我希望它具有我的 MongoDB.
有什么办法吗?? (也许用 insert_many 方法?)
你需要的方法是update_one()
和upsert=True
循环;您不能使用 insert_many()
有两个原因;首先,您并不总是插入;有时你在更新;其次 update_many()
(和 insert_many()
)仅适用于单个过滤器;在您的情况下,每个过滤器都不同,因为每个更新都涉及不同的时间。
这是一种通用解决方案,它将按照您需要的方式组合数据帧(df_a
、df_b
在这种情况下 - 您可以拥有任意数量的数据帧。它使用 iterrows 获取数据框的每一行,过滤日期,并将值设置为数据框中的值。 $set
运算符将覆盖值(如果它们已经存在)并设置它们(如果未设置)。 upsert=True
如果日期不匹配,将执行插入。
for df in [df_a, df_b]:
for _, row in df.iterrows():
db.mycollection.update_one({'date': row.get('date')}, {'$set': row.to_dict()}, upsert=True)
完整的示例:
from pymongo import MongoClient
from pprint import pprint
import datetime
import pandas as pd
# Sample data setup
db = MongoClient()['mydatabase']
data_a = [[datetime.datetime(2017, 5, 19, 21, 20), 96, 8, 98],
[datetime.datetime(2017, 5, 19, 21, 21), 95, 8, 97],
[datetime.datetime(2017, 5, 19, 21, 22), 95, 8, 97]]
df_a = pd.DataFrame(data_a, columns=['date', 'std_500_1000window', 'std_50_100window', 'std_50_2000window'])
data_b = [[datetime.datetime(2017, 5, 19, 21, 20), 98, 9, 10],
[datetime.datetime(2017, 5, 19, 21, 21), 98, 9, 10],
[datetime.datetime(2017, 5, 19, 21, 22), 98, 9, 10]]
df_b = pd.DataFrame(data_b, columns=['date', 'std_50_3000window', 'std_50_300window', 'std_50_500window'])
# Perform the upserts
for df in [df_a, df_b]:
for _, row in df.iterrows():
db.mycollection.update_one({'date': row.get('date')}, {'$set': row.to_dict()}, upsert=True)
# Print the results
for record in db.mycollection.find():
pprint(record)
结果:
{'_id': ObjectId('5f0ae909df5531ac655ce528'),
'date': datetime.datetime(2017, 5, 19, 21, 20),
'std_500_1000window': 96,
'std_50_100window': 8,
'std_50_2000window': 98,
'std_50_3000window': 98,
'std_50_300window': 9,
'std_50_500window': 10}
{'_id': ObjectId('5f0ae909df5531ac655ce52a'),
'date': datetime.datetime(2017, 5, 19, 21, 21),
'std_500_1000window': 95,
'std_50_100window': 8,
'std_50_2000window': 97,
'std_50_3000window': 98,
'std_50_300window': 9,
'std_50_500window': 10}
{'_id': ObjectId('5f0ae909df5531ac655ce52c'),
'date': datetime.datetime(2017, 5, 19, 21, 22),
'std_500_1000window': 95,
'std_50_100window': 8,
'std_50_2000window': 97,
'std_50_3000window': 98,
'std_50_300window': 9,
'std_50_500window': 10}