如何用更Pythonic的方式通过pandas Series.map生成DataFrame多列
更高效的pandas Series转多列DataFrame方法
嘿,这个需求太懂了!当有大量重复的繁重计算时,多次调用apply简直是在浪费资源,必须找个一次搞定的办法。我给你分享几个更Pythonic也更贴合pandas风格的实现方式:
1. 一次性计算所有结果,用apply转DataFrame
最直观的方式就是写一个函数,把每个元素需要的所有计算都在里面完成,返回一个元组(或者列表),然后把apply的结果直接转换成DataFrame。这样整个过程只需要一次逐行处理,完美避免重复计算。
举个实际例子,假设我们要给每个名字生成长度、首字母、是否以元音开头三个特征:
import pandas as pd names = 'Joe Jill Stephen Mark Craig Alexander Emily Connor Cassidy'.split() s = pd.Series(names) def compute_all_features(name): # 这里放所有共享的繁重计算,比如先统一处理名字 lower_name = name.lower() # 一次性生成所有需要的结果 name_length = len(name) first_letter = name[0] starts_with_vowel = lower_name[0] in {'a', 'e', 'i', 'o', 'u'} # 返回一个元组,每个元素对应一列 return name_length, first_letter, starts_with_vowel # 把apply的结果转成DataFrame,再给列命名 df = pd.DataFrame(s.apply(compute_all_features).tolist(), columns=['length', 'first_char', 'starts_with_vowel'])
2. 用pd.DataFrame.from_records提升效率
如果你的数据量比较大,用from_records会比直接转列表更高效,底层实现更优化,用法也很简单:
df = pd.DataFrame.from_records( s.apply(compute_all_features), columns=['length', 'first_char', 'starts_with_vowel'] )
3. 优先选择向量化操作(最pandas风格)
如果你的计算逻辑可以用pandas的向量化API实现,那绝对是最优解!因为apply本质还是Python级别的循环,而向量化操作是用C实现的,速度快很多,代码也更简洁。比如上面的例子可以完全不用apply:
df = pd.DataFrame() df['length'] = s.str.len() df['first_char'] = s.str[0] df['starts_with_vowel'] = s.str.lower().str[0].isin({'a', 'e', 'i', 'o', 'u'})
总结
能向量化就优先向量化,不行就写一个一次性返回所有结果的函数,用一次apply搞定,绝对比多次调用apply重复计算要高效得多!
内容的提问来源于stack exchange,提问作者Jason S
相关产品推荐
相关产品推荐

