python - 从 DataFrame.loc 访问 pandas 数据框中的列表
问题描述
我正在使用一个包含“tchname”列的数据库,每个条目都包含一个字符串,例如“John Smith”或“Mr John Adam Smith”,其中第一个或第二个单词(取决于是否有敬语)每个字符串是名字,最后一个词是姓氏。
我想做的是创建两个新列,“名字”和“姓氏”。获取姓氏很容易,但是我获取名字的方法虽然有效,但感觉非常hacky:
import pandas as pd
# Typical data example:
data = {'tchname': ['MISS NANDA DEVI', 'RAJIK HUSSAIN-III',
'MAJJI VENKATA KANAKA DURGA RANI']}
df = pd.DataFrame(data)
# Split words in teacher names into list.
df['tchname'] = df['tchname'].str.split()
# Extract first word from tchname lists.
df['firstname'] = df['tchname'].str[0].str.title()
# If firstname matches item in honorific, replace with second tchname entry
df['placeholder'] = df['tchname'].str[1].str.title()
honorific = ['Dr', 'Miss', 'Mr', 'Mrs', 'Ms']
df.loc[df['firstname'].isin(honorific), 'firstname'] \
= df.loc[df['firstname'].isin(honorific), 'placeholder']
df = df.drop(columns='placeholder')
# Extract last name from tchname lists.
df['surname'] = df['tchname'].str[-1].str.title()
现在,这正确地将名称识别为“Nanda Devi”、“Rajik Hussain-Iii”和“Majji Rani”。通过使用“占位符”来做到这一点对我来说似乎是一种 hacky 方法。只需几秒钟即可完成(超过数百万个条目的数据库),但是由于它不必要地将无效的名字(例如“小姐”)写入数据库,然后覆盖它们,我想知道是否有我可以采取更好的方法,所以我只在每个条目上迭代并写入数据库一次?
解决方案
感谢 Alexander Cécile 关于使用正则表达式的建议。由于正则表达式的性能不佳,我试图避免这种情况,但是这里有一个基于它的解决方案:
import numpy as np
import pandas as pd
# Typical data example:
data = {'tchname': ['MISS NANDA DEVI', 'RAJIK HUSSAIN-III',
'MAJJI VENKATA KANAKA DURGA RANI']}
df = pd.DataFrame(data)
# Set firstname to first or second word of tchname based on honorific presence.
df['firstname'] = np.where(df['tchname'].str.match(
'^(Dr|Miss|Mr|Mrs|Ms) ', case=False),
df['tchname'].str.split().str[1].str.capitalize(),
df['tchname'].str.split().str[0].str.capitalize())
df['surname'] = df['tchname'].str.split().str[-1].str.capitalize()
我想说代码肯定更清晰,从可维护性的角度来看可能是一个不错的解决方案,但是正如预期的那样,这比原来的运行时间慢(执行时间约为 6.3 秒,而问题中的代码约为 5.4 秒)我的机器使用大型数据集),所以除非没有更好的替代方案建议,否则我不会接受这个答案。
推荐阅读
- r - 使用 Parallelly 包在 R 中运行并行代码时如何解决连接问题?
- javascript - 点击没有在 jquery 中的锚标记上工作
- scala - 线程“主”org.apache.spark.sql.AnalysisException 中的异常:无法解析给定输入列的“id”:[0、33、385、Will];
- javascript - javascript中十进制数的数学计算的数值输出中避免使用科学记数法
- python - 有没有办法通过python脚本而不是使用python(或ipython)shell来运行dtale?
- typescript - 如何从打字稿中的对象中正确删除属性
- c++ - 结构成员的布尔表达式求值器
- python - 如何从锚点旋转 tkinter 画布小部件?
- scala - 抽象类型成员的评估
- reactjs - VS Code JSX 自动格式化程序