
在pandas数据处理中,根据现有列的条件生成新列是常见的需求。例如,我们可能需要根据“姓名输入1”和“姓名输入2”两列的值来决定“姓氏”列的内容。然而,在尝试使用列表推导式同时迭代多个pandas series时,常常会遇到语法错误。
原始尝试直接在列表推导式中用逗号分隔多个Series进行迭代,这会导致语法错误。Python的列表推导式在迭代多个可迭代对象时,需要使用zip()函数将它们打包成一个元组序列,然后对每个元组进行解包迭代。
错误示例(原问题中的代码):
names_df['Surname'] = [
'MISSING' if i != '' and j == '' else j
for i, j in names_df['Name Entry 1'], names_df['Name Entry 2'] # 错误用法
]上述代码的错误在于for i, j in names_df['Name Entry 1'], names_df['Name Entry 2']这一行。Python的for循环无法直接通过逗号同时迭代多个独立的序列。
正确使用 zip() 函数:
zip()函数可以将多个可迭代对象中对应位置的元素打包成一个个元组,然后返回由这些元组组成的迭代器。这是同时遍历多个序列的正确且常用方法。
import pandas as pd
# 示例数据框
data = {
'Name Entry 1': ['John', 'Jane', '', 'Mike', 'Emily'],
'Name Entry 2': ['Doe', 'Smith', 'Johnson', '', 'Brown']
}
names_df = pd.DataFrame(data)
# 使用zip函数修正列表推导式
names_df['Surname'] = [
'MISSING' if i != '' and j == '' else j
for i, j in zip(names_df['Name Entry 1'], names_df['Name Entry 2'])
]
print("使用列表推导式(zip)后的数据框:")
print(names_df)优点:
局限性:
当需要处理多层if/elif/else条件时,将所有逻辑塞进一个列表推导式中会变得非常笨拙。此时,Pandas的apply()方法结合自定义函数是更推荐的选择。通过定义一个清晰的函数来封装复杂的业务逻辑,可以大大提高代码的可读性和可维护性。
实现方式:
import pandas as pd
# 示例数据框(与上文相同)
data = {
'Name Entry 1': ['John', 'Jane', '', 'Mike', 'Emily'],
'Name Entry 2': ['Doe', 'Smith', 'Johnson', '', 'Brown']
}
names_df = pd.DataFrame(data)
# 定义一个处理姓氏逻辑的函数
def determine_surname(row):
"""
根据'Name Entry 1'和'Name Entry 2'的值决定'Surname'。
"""
if row['Name Entry 1'] != '' and row['Name Entry 2'] == '':
return 'MISSING'
# 可以添加更多elif条件来处理更复杂的逻辑
# elif row['Name Entry 1'] == '' and row['Name Entry 2'] != '':
# return 'UNKNOWN'
else:
return row['Name Entry 2']
# 使用apply方法将函数应用到每一行
names_df['Surname'] = names_df.apply(determine_surname, axis=1)
print("\n使用apply函数后的数据框:")
print(names_df)优点:
注意事项:
在Pandas中基于多列条件创建新列时,选择合适的方法至关重要:
最终,选择哪种方法取决于你的具体需求:是追求极致的简洁和性能(简单情况),还是更注重代码的可读性、可维护性和对复杂逻辑的良好支持(复杂情况)。
以上就是Pandas数据框多列条件赋值:列表推导与apply函数实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号