
本文旨在提供一种高效且健壮的方法,用于将具有不同长度的列表数据作为新列添加到现有pandas dataframe中,特别是在循环场景下避免dataframe碎片化带来的性能问题。通过巧妙结合使用`itertools.zip_longest`进行数据填充和`pd.concat`进行高效合并,本教程将展示如何灵活处理变长数据,确保数据整合的效率和准确性。
在数据分析和处理中,我们经常需要将新的数据列动态地添加到现有的Pandas DataFrame中。然而,当这些新数据来源于列表,并且其内部子列表长度不一致时,直接操作可能会遇到挑战,尤其是在循环中重复添加大量列时,可能导致DataFrame碎片化,从而引发性能警告甚至错误。本教程将详细介绍如何优雅地解决这一问题。
假设我们有以下两组数据:
我们还有一个初始的Pandas DataFrame df:
import pandas as pd
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)期望的结果是,将list1作为新列名,list2作为对应行的值,添加到df中,其中list2中较短的子列表应使用默认值(例如0)进行填充,以匹配list1的长度。
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
一种直观但可能效率不高的方法是尝试直接将list2转换为DataFrame并赋值:
# 假设 list2 已经经过处理,使其内部子列表长度一致 # df[list1] = pd.DataFrame(list2, index=df.index)
然而,这种方法存在几个问题:
为了避免这些问题,我们需要一个更健壮和高效的解决方案。
该解决方案的核心思想是:
首先,导入必要的库和定义初始数据:
from itertools import zip_longest
import pandas as pd
# 原始数据
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'])接下来是核心处理逻辑:
# 1. 使用 zip_longest 填充 list2 中的子列表
# 这一步的目的是确保 list2 中的每个子列表都具有相同的长度,
# 且该长度与 list1 (列名) 的长度匹配,不足部分用 fillvalue 填充。
# 具体操作:
# - zip_longest(*list2, fillvalue=0) 将 list2 视为多行数据,
# 进行“转置”并填充,例如 [1,2,3], [2,3] 会变成 (1,2), (2,3), (3,0)。
# - 外层的 zip(*...) 再次进行“转置”,将填充后的数据恢复到
# 原始的“行”结构,但现在所有行都已补齐到最大长度。
# 示例:
# list2_padded = [[1, 2, 3, 0], [2, 3, 0, 0], [1, 8, 4, 3], [22, 35, 32, 0], [65, 0, 0, 0], [2, 45, 55, 0]]
list2_padded = list(zip(*zip_longest(*list2, fillvalue=0)))
# 2. 将填充后的数据与列名 list1 结合,创建字典列表
# 对于 list2_padded 中的每一行 (vals),将其与 list1 (列名) 进行 zip,
# 然后转换为字典,形成 {col_name: value} 的结构。
# 示例:
# [{'col1': 1, 'col2': 2, 'col3': 3, 'col4': 0}, ...]
new_data_dicts = [dict(zip(list1, vals)) for vals in list2_padded]
# 3. 从字典列表创建新的 DataFrame
new_df_cols = pd.DataFrame(new_data_dicts)
# 4. 使用 pd.concat 将新旧 DataFrame 横向合并
# axis=1 表示按列合并。这是添加新列的高效方式,避免了碎片化。
out = pd.concat([df, new_df_cols], axis=1)
print("\n整合后的DataFrame:")
print(out)原始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
整合后的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通过上述方法,我们可以优雅且高效地将变长列表数据整合到Pandas DataFrame中,同时避免常见的性能陷阱,确保数据处理流程的顺畅和可靠。
以上就是高效地将变长列表数据整合到Pandas DataFrame中:避免性能碎片化的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号