You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从MongoDB游标嵌套数据构建统一Pandas DataFrame?

如何从MongoDB嵌套文档中提取数据并构建统一的Pandas DataFrame

你的问题很典型——从MongoDB的嵌套文档里提取数组数据,合并成一个能用于补全其他DataFrame缺失值的统一DataFrame。之前你得到的是DataFrame列表,核心问题是没有对列表里的小DataFrame进行合并操作,下面给你两种实用的解决方案:

方法一:改进现有代码,用pd.concat合并DataFrame列表

你原来的代码已经正确提取了每个文档的prices数据,只需要最后一步把所有小DataFrame合并起来就行,还可以顺便添加文档的元数据(比如modelRun、Type),方便后续和其他DataFrame关联:

def extract_prices_to_df(cursor_real):
    all_df_real = []
    for doc in cursor_real:
        # 避免因缺失字段抛出KeyError
        if 'data' in doc and 'prices' in doc['data']:
            single_real_df = pd.DataFrame(doc['data']['prices'])
            # 添加当前文档的标识字段,方便后续关联补值
            single_real_df['modelRun'] = doc['modelRun']
            single_real_df['Type'] = doc['Type']
            all_df_real.append(single_real_df)
    # 合并所有DataFrame,重置索引避免重复
    combined_df = pd.concat(all_df_real, ignore_index=True)
    return combined_df

调用这个函数就能直接得到你需要的统一DataFrame了,ignore_index=True会帮你重置整个DataFrame的索引,避免不同小DataFrame的索引冲突。

方法二:先收集所有数据再转DataFrame(更高效)

如果你的游标里有大量文档,多次创建小DataFrame再合并会有性能开销,推荐先把所有prices条目(加上元数据)收集到一个列表里,再一次性转成DataFrame:

def extract_prices_to_df(cursor_real):
    all_prices = []
    for doc in cursor_real:
        if 'data' in doc and 'prices' in doc['data']:
            # 给每个price条目添加文档的元数据
            for price_entry in doc['data']['prices']:
                price_entry['modelRun'] = doc['modelRun']
                price_entry['Type'] = doc['Type']
                all_prices.append(price_entry)
    # 一次性生成完整DataFrame
    combined_df = pd.DataFrame(all_prices)
    return combined_df

这种方式减少了多次DataFrame对象的创建和合并操作,在数据量较大时性能提升明显。

为什么你之前的尝试没成功?

  • 你原来的代码只把每个文档的prices转成DataFrame并加入列表,没有执行合并步骤,所以返回的是DataFrame列表而非统一DataFrame;
  • 如果你尝试创建空DataFrame后结果为空,大概率是因为没有正确处理数据追加(比如误用了df.append(),或者没有判断字段是否存在导致数据没被添加)。

内容的提问来源于stack exchange,提问作者nrvaller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:03:06