
在数据分析和处理中,我们经常会遇到需要确保数据集的完整性,尤其是在按某些字段进行分组时。例如,你可能有一个包含人员姓名、交易类型和交易金额的数据集。你希望确保每个人(由“名”和“姓”唯一标识)都拥有所有预定义的交易类型(如“存款”、“取款”、“转账”等),即使某些人从未进行过某种类型的交易。对于这些缺失的交易类型,我们需要创建新的行,并为其数值字段填充一个默认值(例如0)。
示例数据:
假设我们有以下DataFrame,其中包含“First Name”、“Last Name”、“Type”和“Value”四列。我们还有一个预定义的完整types列表。
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)在这个例子中,Bob Jack这个组合缺少DA和FA两种类型。我们的目标是为Bob Jack创建两行新数据,分别对应DA和FA类型,并将Value设置为0。
解决此问题的核心思路是:
首先,我们需要从原始DataFrame中提取所有唯一的First Name和Last Name组合。
# 提取唯一的姓名组合
unique_names = df[['First Name', 'Last Name']].drop_duplicates()
print("\n唯一的姓名组合:")
print(unique_names)接下来,我们将这些唯一的姓名组合与预定义的types列表进行交叉连接。Pandas 1.2.0及以上版本提供了DataFrame.merge(how='cross')方法,可以方便地实现笛卡尔积。
# 将types列表转换为DataFrame Series,方便交叉连接
all_types_series = pd.Series(types, name='Type')
# 交叉连接,生成所有可能的姓名-类型组合
all_combinations = unique_names.merge(all_types_series, how='cross')
print("\n所有可能的姓名-类型组合:")
print(all_combinations)现在,我们将all_combinations这个包含所有可能组合的DataFrame与原始DataFrame df进行左连接。连接键是['First Name', 'Last Name', 'Type']。左连接的特性是,如果all_combinations中的某个组合在df中不存在,那么df中对应的其他列(如Value)将填充NaN。
# 与原始DataFrame进行左连接
merged_df = all_combinations.merge(df, on=['First Name', 'Last Name', 'Type'], how='left')
print("\n左连接后的DataFrame (包含NaN值):")
print(merged_df)可以看到,Bob Jack的DA和FA类型对应的Value列现在是NaN。
最后一步是使用默认值(例如0)填充所有NaN值。需要注意的是,当Value列中出现NaN时,Pandas会自动将其数据类型提升为浮点型(float)。如果需要保持整数类型,我们需要在填充后进行类型转换。
# 填充NaN值为0
filled_df = merged_df.fillna(0)
# 将'Value'列转换回整数类型
final_df = filled_df.astype({'Value': int})
print("\n最终结果DataFrame:")
print(final_df)将上述步骤整合到一起,形成一个简洁、链式调用的解决方案:
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)
# 完整的解决方案
output_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') # 与原始DataFrame左连接
.fillna(0) # 填充NaN值为0
.astype({'Value': int}) # 将Value列转换回整数类型
)
print("最终生成的DataFrame:")
print(output_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 DA 0 6 Bob Jack FA 0 7 Bob Jack GCA 37
可以看到,Bob Jack的DA和FA类型已成功创建,并且Value列被设置为0。
通过上述方法,我们能够有效地为分组数据补齐缺失的类型组合行,确保数据结构的完整性和一致性,这在数据报告、分析和机器学习预处理中都非常有用。
以上就是Pandas教程:为分组数据填充缺失的类型组合行的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号