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

如何从长度不均的字典创建Pandas DataFrame?求类似R tidyr::fill的方法

Python中实现类似R tidyr::fill的列填充重复效果

当然有!针对你提出的需求——将字典中所有短列重复自身内容至最长列的长度,我们可以用几种简洁的方式实现,效果类似R里tidyr::fill的填充逻辑,甚至更直接。

方法一:直接计算长度并重复元素

这是最直观的方式,先找到最长列的长度,再将每个短列的内容重复到该长度:

import pandas as pd

# 你的原始字典
d = {"a": [1], "b": 2, "c": [[7, 8, 9], ["a", "b", "c"], [9, 10, 11]], "d": None}

# 第一步:计算所有列的最大长度
def get_column_length(value):
    # 如果是列表,取列表长度;否则视为长度1的元素
    return len(value) if isinstance(value, list) else 1

max_length = max(get_column_length(v) for v in d.values())

# 第二步:处理每个列,将内容重复到最大长度
processed_dict = {}
for key, val in d.items():
    if isinstance(val, list):
        # 列表类型:直接重复整个列表到目标长度
        processed_dict[key] = val * max_length
    else:
        # 非列表类型:包装成列表后重复
        processed_dict[key] = [val] * max_length

# 生成目标DataFrame
df = pd.DataFrame(processed_dict)

运行后得到的df就是你想要的结果:

a  b                c     d
0  [1]  2  [7, 8, 9]     None
1  [1]  2  ['a', 'b', 'c']  None
2  [1]  2  [9, 10, 11]     None

方法二:先补NA再向前填充(更贴近R tidyr::fill逻辑)

如果你更习惯R中先构造含NA的数据集再填充的思路,也可以用Pandas的ffill()方法实现:

import pandas as pd
import numpy as np

d = {"a": [1], "b": 2, "c": [[7, 8, 9], ["a", "b", "c"], [9, 10, 11]], "d": None}

max_length = max(len(v) if isinstance(v, list) else 1 for v in d.values())

# 先构造每个列的列表,短列用NA补全长度
temp_data = {}
for key, val in d.items():
    if isinstance(val, list):
        temp_list = val.copy()
        # 补NA到最大长度
        temp_list += [np.nan] * (max_length - len(temp_list))
    else:
        temp_list = [val] + [np.nan] * (max_length - 1)
    temp_data[key] = temp_list

# 用ffill()向前填充NA,实现重复效果
df = pd.DataFrame(temp_data).ffill()

这种方法的逻辑和R的tidyr::fill完全一致:先让所有列长度统一(短列补NA),再将非NA值向下填充覆盖NA位置。

注意事项

  • 对于列表类型的元素,第一种方法会直接重复整个列表作为元素,更符合你的需求;
  • 如果你的数据中包含复杂类型(比如嵌套列表),第二种方法要注意np.nan的类型兼容问题,不过大多数情况下两种方法都能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:07:32