
本文详细阐述了如何高效且优雅地将外部变长列表数据作为新列添加到现有Pandas DataFrame中,同时避免因频繁操作或数据长度不一致导致的性能碎片化警告。通过结合Python的`itertools.zip_longest`函数处理数据对齐与填充,并利用Pandas的`pd.concat`进行一次性合并,本教程提供了一种在处理动态或迭代数据添加场景下的优化策略,确保数据处理的效率和稳定性。
在数据分析和处理中,我们经常需要将外部数据源集成到现有的Pandas DataFrame中。一个常见的挑战是,当需要添加的数据以列表形式存在,并且这些列表的长度可能不一致时。更复杂的是,当这种添加操作需要在循环中重复执行,或者涉及大量列时,不当的处理方式可能导致显著的性能问题,例如Pandas发出的“DataFrame is highly fragmented”(DataFrame高度碎片化)警告。本教程将介绍一种健壮且高效的方法来解决这一问题。
考虑以下场景:我们有一个列名列表(list1)和一个包含多个子列表的列表(list2),其中每个子列表代表一行数据,且它们的长度可能不同。我们的目标是将list1中的元素作为新的列名,list2中的数据填充到这些新列中,并与现有DataFrame的行对齐,对于缺失的数据点(由于子列表长度不足)填充一个默认值(例如0)。
直接使用类似df[list1] = pd.DataFrame(list2, index=df.index)的方式,虽然在某些简单情况下可行,但当list2中的子列表长度不一致时,会遇到数据对齐问题。更重要的是,在循环中反复对DataFrame进行列的增删改查操作,会导致DataFrame的内存布局变得碎片化,从而降低后续操作的性能。
为了高效地解决上述问题,我们将利用Python标准库中的itertools.zip_longest函数来处理变长列表的对齐和填充,然后通过构建一个完整的临时DataFrame并使用pd.concat进行一次性合并,从而避免性能碎片化。
首先,我们定义初始的列名列表、数据列表和现有的DataFrame:
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]]
# 现有DataFrame
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)原始DataFrame df 如下:
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
itertools.zip_longest是处理多个可迭代对象时,当它们长度不一致时进行填充的强大工具。在这里,我们将利用它来确保list2中的每个子列表都被填充到与list1相同(或至少是list2中最长子列表)的长度。
核心思想是使用zip(*zip_longest(*list2, fillvalue=0))这个模式。让我们逐步解析:
# 使用itertools.zip_longest处理变长列表,并填充缺失值
# zip(*zip_longest(*list2, fillvalue=0)) 的作用是:
# 1. zip_longest(*list2, fillvalue=0) 先将list2进行“转置”,同时用fillvalue填充短的子列表
# 例如:list2 = [[1,2,3], [2,3]] -> (1,2), (2,3), (3,0)
# 2. 外层的 zip(*...) 再将结果“转置”回来,此时每个原始子列表都被填充到了最长子列表的长度
# 例如:(1,2), (2,3), (3,0) -> (1,2,3), (2,3,0)
padded_data_rows = [
dict(zip(list1, vals))
for vals in zip(*zip_longest(*list2, fillvalue=0))
]
# 将处理后的数据转换为新的DataFrame
new_cols_df = pd.DataFrame(padded_data_rows)
print("\n新生成列的DataFrame:")
print(new_cols_df)new_cols_df 的输出将是:
col1 col2 col3 col4 0 1 2 3 0 1 2 3 0 0 2 1 8 4 3 3 22 35 32 0 4 65 0 0 0 5 2 45 55 0
可以看到,list2中的每个子列表都已根据list1的长度(或list2中最长子列表的长度)进行了填充,缺失值用0表示。
最后一步是将原始DataFrame df 与新生成的列DataFrame new_cols_df 进行合并。我们使用pd.concat函数,并指定axis=1表示按列合并。
# 使用pd.concat将原始DataFrame与新列DataFrame合并
out_df = pd.concat([df, new_cols_df], axis=1)
print("\n最终合并后的DataFrame:")
print(out_df)最终的DataFrame out_df 如下:
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
这正是我们期望的结果。
本教程提供了一种在Pandas中高效处理变长列表数据并将其作为新列添加到DataFrame的专业方法。通过巧妙地结合itertools.zip_longest进行数据对齐和填充,并利用pd.DataFrame和pd.concat进行批处理式合并,我们不仅解决了数据长度不一致的问题,还显著提升了性能,避免了常见的DataFrame碎片化警告。这种方法尤其适用于需要动态生成和集成数据到DataFrame的复杂场景。
以上就是高效集成变长列表数据至Pandas DataFrame:避免性能碎片化的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号