新闻中心

高效地将变长列表数据整合到Pandas DataFrame

2025-11-13
浏览次数:
返回列表

高效地将变长列表数据整合到pandas dataframe

本文旨在提供一种高效且避免DataFrame碎片化的方法,将包含不同长度子列表的数据以及对应的列名列表整合到现有的Pandas DataFrame中。我们将利用Python的`itertools.zip_longest`函数处理变长数据,并通过巧妙的转置与字典构建,最终使用`pd.concat`将新数据作为列安全地添加到DataFrame,尤其适用于在循环中动态添加大量列的场景。

在数据分析和处理中,我们经常需要将外部数据源(例如来自API响应或动态生成的数据)整合到现有的Pandas DataFrame中。一个常见的挑战是,当这些外部数据以列表形式存在,并且其内部结构(例如子列表的长度)不一致时,如何高效且正确地将其作为新列添加到DataFrame。直接的列表到DataFrame赋值操作有时会导致性能问题,例如PerformanceWarning: DataFrame is highly fragmented。本教程将介绍一种结合itertools.zip_longest和pd.concat的专业方法来解决这一问题。

问题场景分析

假设我们有以下数据:

  1. 一个列名列表 list1,例如 ['col1', 'col2', 'col3', 'col4']。
  2. 一个包含变长子列表的数据列表 list2,例如 [[1, 2, 3], [2, 3], [1, 8, 4, 3], [22, 35, 32], [65], [2, 45, 55]]。
  3. 一个现有的Pandas DataFrame df。

我们的目标是将 list1 中的元素作为新列名,list2 中的数据作为对应的新行数据添加到 df 中,同时处理 list2 中子列表长度不一致的问题,并用默认值(例如0)填充缺失的数据。

直接尝试 df[list1] = pd.DataFrame(list2, index=df.index) 的方法可能导致DataFrame碎片化警告,尤其当在循环中反复执行此操作时,会严重影响性能。这是因为Pandas在每次添加新列时可能需要重新分配内存,而不是高效地在现有内存块上扩展。

解决方案:结合 itertools.zip_longest 和 pd.concat

为了解决上述问题,我们将采用以下策略:

  1. 使用 itertools.zip_longest 处理 list2 中的变长子列表,确保所有子列表都被填充到相同的长度。
  2. 通过巧妙的转置操作,将填充后的数据转换为适合构建新DataFrame的格式。
  3. 将处理后的数据转换为字典列表,以便Pandas能够正确地将其映射到 list1 中的列名。
  4. 使用 pd.concat 函数将新生成的DataFrame与原始DataFrame沿列方向合并,这是添加大量列或在循环中添加列时推荐的高效方法。

核心概念:itertools.zip_longest

itertools.zip_longest 是Python标准库中的一个函数,它类似于内置的 zip 函数,但可以处理不同长度的迭代器。当一个迭代器耗尽时,它会用指定的 fillvalue 填充缺失的值,直到最长的迭代器耗尽。

SecLists SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

SecLists 37 查看详情 SecLists

在我们的场景中,list2 包含多个子列表。为了将这些子列表的元素作为新列的数据,我们需要确保每个子列表都具有与 list1 相同的长度。zip_longest 可以帮助我们实现这一点。

详细步骤与代码示例

首先,我们定义初始数据:

import pandas as pd
from itertools import zip_longest

# 原始数据
list1 = ['col1', 'col2', 'col3', 'col4']
list2 = [[1, 2, 3], [2, 3], [1, 8, 4, 3], [22, 35, 32], [65], [2, 45, 55]]

df = pd.DataFrame([
    ['Alex', 33, 'Male'],
    ['Marly', 28, 'Female'],
    ['Charlie', 30, 'Female'],
    ['Mimi', 37, 'Female'],
    ['James', 44, 'Male'],
    ['Jone', 25, 'Male']
], columns=['Name', 'Age', 'Gender'])

print("原始DataFrame:")
print(df)
print("\n待添加的列名:", list1)
print("待添加的数据 (变长列表):", list2)

接下来是处理 list2 并构建新DataFrame的关键部分:

# 步骤1: 使用 zip_longest 填充并转置 list2
# zip_longest(*list2, fillvalue=0) 会将 list2 视为多列进行转置,
# 并且用 fillvalue=0 填充较短的“行”(即原始子列表中的元素)。
# 例如,如果 list2 是 [[1,2,3], [4,5]],zip_longest(*list2, fillvalue=0) 会得到 (1,4), (2,5), (3,0)。
# 它的输出是按“列”组织的,但我们想要按“行”组织的填充数据。
transposed_and_padded = zip_longest(*list2, fillvalue=0)

# 步骤2: 再次使用 zip 进行转置,将数据恢复为按行组织的填充子列表
# zip(*transposed_and_padded) 将把上面按“列”组织的结果再次转置回来,
# 此时每个元素都是一个填充到最长长度的原始子列表。
# 例如,如果上一步得到 (1,4), (2,5), (3,0),这一步会得到 (1,2,3), (4,5,0)。
# 确保每个子列表的长度与 list1 的长度(即所需列数)一致。
# 在本例中,list1 的长度是4,而 list2 中最长子列表的长度也是4。
# 如果 list1 的长度大于 list2 中子列表的最大长度,
# 我们还需要额外处理以确保最终字典的键值对数量正确匹配。
# 但在这里,list1的长度决定了最终列数,zip_longest已经处理了子列表的内部长度。
# 实际上,zip(*zip_longest(*list2, fillvalue=0)) 的结果是:
# [(1, 2, 3, 0), (2, 3, 0, 0), (1, 8, 4, 3), (22, 35, 32, 0), (65, 0, 0, 0), (2, 45, 55, 0)]
# 这里的每个元组都代表一行数据,且长度与 list1 相同。
padded_rows = zip(*transposed_and_padded)

# 步骤3: 将填充后的行数据与列名 list1 组合成字典列表
# 每个字典代表 DataFrame 的一行,键是列名,值是对应的数据。
new_data_dicts = [dict(zip(list1, vals)) for vals in padded_rows]

# 步骤4: 创建新的DataFrame
new_df_columns = pd.DataFrame(new_data_dicts)

# 步骤5: 使用 pd.concat 将新DataFrame与原始DataFrame合并
# axis=1 表示按列合并。
out_df = pd.concat([df, new_df_columns], axis=1)

print("\n整合后的DataFrame:")
print(out_df)

输出结果:

原始DataFrame:
     Name  Age  Gender
0    Alex   33    Male
1   Marly   28  Female
2  Charlie   30  Female
3     Mimi   37  Female
4   James   44    Male
5    Jone   25    Male

待添加的列名: ['col1', 'col2', 'col3', 'col4']
待添加的数据 (变长列表): [[1, 2, 3], [2, 3], [1, 8, 4, 3], [22, 35, 32], [65], [2, 45, 55]]

整合后的DataFrame:
      Name  Age  Gender  col1  col2  col3  col4
0     Alex   33    Male     1     2     3     0
1    Marly   28  Female     2     3     0     0
2  Charlie   30  Female     1     8     4     3
3     Mimi   37  Female    22    35    32     0
4    James   44    Male    65     0     0     0
5     Jone   25    Male     2    45    55     0

代码解释

  1. zip_longest(*list2, fillvalue=0): 这一步是处理变长子列表的关键。*list2 将 list2 中的每个子列表作为单独的参数传递给 zip_longest。zip_longest 会将这些子列表“垂直”地组合起来,形成元组,并且用 fillvalue=0 填充那些较短子列表的缺失位置。例如,list2[0] (1,2,3) 和 list2[1] (2,3) 会被处理成 (1,2), (2,3), (3,0)。
  2. zip(*transposed_and_padded): 由于 zip_longest 第一次转置后是按“列”组织数据的,我们需要再次使用 zip 进行“垂直”转置,将其恢复为按“行”组织的数据。经过这两次转置,list2 中的每个子列表都变成了长度一致的元组,其中不足的长度用 fillvalue 填充。
  3. [dict(zip(list1, vals)) for vals in padded_rows]: 这一步遍历 padded_rows 中每个填充后的行数据元组 (vals)。zip(list1, vals) 将列名 (list1 中的元素) 与行数据 (vals 中的元素) 配对,然后 dict() 将这些配对转换为字典。最终得到一个字典列表,每个字典代表新DataFrame的一行。
  4. pd.DataFrame(new_data_dicts): 使用这个字典列表创建新的DataFrame,它包含了所有要添加的新列和数据。
  5. pd.concat([df, new_df_columns], axis=1): 这是将新列添加到现有DataFrame的最佳实践。pd.concat 在 axis=1 的情况下,会沿着列方向合并两个DataFrame,避免了逐列赋值可能导致的DataFrame碎片化问题,从而提高了性能。

注意事项与最佳实践

  • fillvalue的选择: zip_longest 的 fillvalue 参数非常重要。对于数值数据,通常选择 0 或 np.nan。对于字符串或混合类型数据,可以考虑 None 或空字符串 ''。选择合适的填充值对于后续的数据分析至关重要。
  • 性能优势: 这种方法通过一次性创建新的DataFrame并使用 pd.concat 进行合并,显著优于在循环中逐列赋值或直接将一个可能导致碎片化的DataFrame赋给多列。在处理大数据集或需要频繁更新DataFrame的场景下,性能提升尤为明显。
  • 列名与数据匹配: 确保 list1 的长度与 zip(*zip_longest(...)) 结果中每个元组的长度一致。通常,list1 定义了最终的列数,而 zip_longest 确保了数据行的长度与最长子列表的长度一致。如果 list1 的长度大于 list2 中子列表的最大长度,zip(list1, vals) 会自动截断 list1 以匹配 vals 的长度,或者如果 vals 更短,list1 的多余部分会被忽略。为了精确控制,应确保 list1 的长度与 zip_longest 填充后的行长度一致。在我们的例子中,list1 的长度为4,list2 中最长子列表的长度也是4,因此完美匹配。
  • 索引对齐: pd.concat 会根据索引进行对齐。在本例中,由于 new_df_columns 是从头创建的,其默认索引将是 0, 1, 2...,这与原始 df 的索引一致,因此合并会很顺利。如果 df 有自定义索引,并且希望新数据也遵循该索引,可以在创建 new_df_columns 时通过 index=df.index 显式指定。

总结

本教程提供了一种健壮且高效的方法,用于将包含变长子列表的数据作为新列添加到Pandas DataFrame中。通过利用 itertools.zip_longest 智能地填充数据,并结合 pd.concat 的高效合并机制,我们不仅解决了数据长度不一致的问题,还避免了DataFrame碎片化带来的性能开销。这种方法尤其适用于需要在循环中动态扩展DataFrame的复杂数据处理场景,是Pandas用户进行高级数据整合的有力工具。

以上就是高效地将变长列表数据整合到Pandas DataFrame的详细内容,更多请关注其它相关文章!


# 迭代  # 常州自贡网站建设推广  # 流量时代营销推广法则  # 智能化营销推广服务保障  # 雅安网站推广怎么选  # 会展怎么营销推广产品呢  # 楚雄市城乡建设局网站  # 儋州网站推广外包服务  # 网站内容优化有哪些内容  # nft营销推广感悟  # 微信全员营销的产品推广  # 会将  # 显存  # python  # 所需  # 适用于  # 转换为  # 这是  # 行数  # 将其  # 变长  # 标准库  # 键值对  # 数据恢复  # 工具  # 大数据 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 网易大神怎么保存别人动态的图片_网易大神动态图片保存方法  Win11如何使用Windows Sandbox Win11沙盒功能开启与使用教程【详解】  4399网页游戏电脑版全新入口 4399电脑端在线玩指南  React列表渲染与独立状态管理:避免全局状态影响局部更新  双系统安装时,如何设置默认启动系统? msconfig命令了解一下!  海棠电脑版入口_通过电脑访问海棠官网阅读  J*a 递归快速排序中静态变量的状态管理与陷阱  处理动态列数据:J*a ArrayList的正确初始化与字符累加教程  拼多多视频播放卡顿如何处理 拼多多视频播放优化技巧  腾讯视频怎么举报不良内容_腾讯视频内容举报流程与违规信息处理方法  FullCalendar 自定义按钮样式定制指南  漫蛙Manwa2官网入口地址分享 漫蛙漫画PC版永久访问通道  蛙漫官网漫画入口地址_蛙漫在线畅读无广告弹窗  PHP 枚举:根据字符串获取枚举案例的策略与实现  深入理解J*aScript中的B样条曲线与节点向量生成  C++如何生成随机数_C++ random库使用方法与范围设置  word中如何让数字纵向排列_Word数字纵向排列方法  微信网页版官方入口教程 微信网页版网页版快速登录步骤  163邮箱登录密码 163邮箱忘记密码找回  妖精动漫免费平台 妖精动漫官网资源观看网址  Lar*el 递归关系中排除指定分支的教程  必由学在线入口 必由学网页版快速登录入口  一加 14R 快充无反应_一加 14R 充电优化  CSS如何设置hover状态颜色_hover伪类调整背景或文字颜色  谷歌google账号怎么注册账号 谷歌账号注册官方流程  C++编译期如何执行复杂计算_C++模板元编程(TMP)技巧与应用  铁路12306官网网页端快速入口 铁路12306官方首页登录教程  谷歌学术网站直达地址 谷歌学术搜索网页版一键进入  在FastAPI中利用lifespan与依赖注入高效管理Redis连接池  动漫花园资源网使用步骤_动漫花园资源网下载流程  TikTok评论显示延迟如何处理 TikTok评论刷新优化方法  解决macOS Tkinter应用双击启动崩溃:PyInstaller打包指南  蛙漫漫画官网在线入口 蛙漫全本漫画免费阅读平台  Excel文件在线转换快速入口 Excel在线格式转换网站  QQ邮箱官网登录入口 QQ邮箱网页版邮箱快速登录  精准捕获:如何在页面中监听除特定元素外的所有点击事件  163邮箱注册官网 免费申请163个人邮箱  Windows10怎么开启夜间模式 Windows10系统设置调整色温与亮度缓解夜间用眼疲劳【教程】  漫蛙2在线漫画入口 漫蛙正版漫画网页版直达  如何使用Go和Martini动态服务解码后的图片  韩剧圈正版入口页面_韩剧圈官网登录链接  漫蛙2漫画入口 漫蛙正版网页漫画直达网址  深入理解字体排版:Adobe光学字偶距与CSS字偶距的差异与实现  C++如何操作注册表_Windows平台下C++读写注册表的API函数详解  Surface怎么安装系统 微软Surface Pro U盘重装win11教程  J*aScript中如何高效提取对象指定属性  J*aScript Promise链中如何正确终止后续.then执行并处理错误  cad怎么合并重叠的线段_cad清理重复重叠线条的操作方法  AO3官方镜像站点汇总 AO3同人作品网页版直达链接  PHP中获取MongoDB服务器运行时间(Uptime)的专业指南 

搜索