
在数据分析和处理中,我们经常会遇到需要确保数据集完整性的情况。例如,在一个包含多个分组(如姓名)和多个类别(如交易类型)的dataframe中,我们可能需要确保每个分组都包含了所有预定义的类别,即使某些类别在原始数据中并未出现。对于这些缺失的组合,我们通常需要创建新的行并填充默认值(例如0),以保持数据结构的统一性。
考虑以下示例DataFrame,它记录了不同人员的交易类型和对应的值:
import pandas as pd
data = {
'First Name': ['Alice', 'Alice', 'Alice', 'Alice', 'Bob', 'Bob'],
'Last Name': ['Johnson', 'Johnson', 'Johnson', 'Johnson', 'Jack', 'Jack'],
'Type': ['CA', 'DA', 'FA', 'GCA', 'CA', 'GCA'],
'Value': [25, 30, 35, 40, 50, 37]
}
types = ['CA', 'DA', 'FA', 'GCA']
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)在这个例子中,我们定义了四种可能的交易类型:types = ['CA', 'DA', 'FA', 'GCA']。观察DataFrame,我们可以发现:
我们的目标是为 Bob Jack 补充缺失的 DA 和 FA 类型行,并将它们的 Value 设置为0,从而使每个姓名组合都拥有所有四种交易类型的数据。
解决此类问题的核心思路是:
下面是具体的Pandas实现步骤:
首先,从原始DataFrame中提取所有唯一的 First Name 和 Last Name 组合。
unique_names = df[['First Name', 'Last Name']].drop_duplicates()
print("\n唯一的姓名组合:")
print(unique_names)接下来,利用 merge(how='cross') 方法将唯一的姓名组合与所有 types 进行笛卡尔积操作。pd.Series(types, name='Type') 将 types 列表转换为一个Series,以便进行交叉合并。
all_combinations = unique_names.merge(pd.Series(types, name='Type'), how='cross')
print("\n所有姓名与类型组合的骨架:")
print(all_combinations)all_combinations 现在包含了 Alice Johnson 与所有 types 的组合,以及 Bob Jack 与所有 types 的组合。
将 all_combinations 作为左表,与原始 df 进行左连接。连接键是 ['First Name', 'Last Name', 'Type']。由于 all_combinations 包含了所有预期的组合,左连接将保留这些组合,并从 df 中匹配对应的数据。对于 df 中不存在的组合,其 Value 列将变为 NaN。
最后,使用 fillna(0) 将所有 NaN 值替换为0。需要注意的是,当 Value 列包含 NaN 时,Pandas 会自动将其数据类型转换为浮点型(float)。如果需要保持整数类型,可以在填充后使用 astype({'Value': int}) 进行转换。
out = (all_combinations
.merge(df, on=['First Name', 'Last Name', 'Type'], how='left')
.fillna(0)
# 如果需要将Value列转换回整数类型,请使用此行
.astype({'Value': int})
)
print("\n填充缺失值后的DataFrame:")
print(out)将上述步骤整合,得到以下简洁高效的解决方案:
import pandas as pd
# 示例数据
data = {
'First Name': ['Alice', 'Alice', 'Alice', 'Alice', 'Bob', 'Bob'],
'Last Name': ['Johnson', 'Johnson', 'Johnson', 'Johnson', 'Jack', 'Jack'],
'Type': ['CA', 'DA', 'FA', 'GCA', 'CA', 'GCA'],
'Value': [25, 30, 35, 40, 50, 37]
}
types = ['CA', 'DA', 'FA', 'GCA']
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)
# 生成完整组合并填充缺失值
result_df = (df[['First Name', 'Last Name']]
.drop_duplicates()
.merge(pd.Series(types, name='Type'), how='cross')
.merge(df, on=['First Name', 'Last Name', 'Type'], how='left')
.fillna(0)
.astype({'Value': int}) # 将Value列转换回整数类型
)
print("\n处理后的DataFrame:")
print(result_df)输出结果:
原始DataFrame: First Name Last Name Type Value 0 Alice Johnson CA 25 1 Alice Johnson DA 30 2 Alice Johnson FA 35 3 Alice Johnson GCA 40 4 Bob Jack CA 50 5 Bob Jack GCA 37 处理后的DataFrame: First Name Last Name Type Value 0 Alice Johnson CA 25 1 Alice Johnson DA 30 2 Alice Johnson FA 35 3 Alice Johnson GCA 40 4 Bob Jack CA 50 5 Bob Jack DA 0 6 Bob Jack FA 0 7 Bob Jack GCA 37
从输出可以看出,Bob Jack 的 DA 和 FA 类型行已被成功创建,并且 Value 列被填充为0,数据类型也保持为整数。
通过巧妙地结合 drop_duplicates() 提取唯一组键、merge(how='cross') 生成所有可能组合,以及 merge(how='left') 和 fillna() 填充缺失值,我们可以高效且优雅地解决Pandas中分组数据缺失特定组合行的问题。这种技术确保了数据结构的完整性和一致性,为后续的数据分析和报表生成奠定了坚实的基础。
以上就是Pandas教程:填充分组数据中缺失的特定组合行的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号