以下是可用的数据框:
+--------------------+
| Name|
+--------------------+
|Braund, Mr. Owen ...|
|Cumings, Mrs. Joh...|
|Heikkinen, Miss. ...|
|Futrelle, Mrs. Ja...|
|Allen, Mr. Willia...|
|Moran, Mr. James|
|McCarthy, Mr. Tim...|
|Palsson, Master. ...|
|Johnson, Mrs. Osc...|
+--------------------+
我想使用Pyspark在DATA FRAME的每一行中找到第一次出现Title和Surname(我的群集中没有Pandas lib)。
pattern=re.compile(r'(Dr|Mrs?|Ms|Miss|Master|Rev|Capt|Mlle|Col|Major|Sir|Lady|Mme|Don)\\.'
pattern.match(df['Name'])
答案 0 :(得分:0)
如果Name
列的'姓氏'作为第一个单词,那么你可以试试这个,否则正则表达式需要稍微调整一下。
from pyspark.sql.functions import regexp_extract, col
#sample data
df= sc.parallelize([["Braund, Mr. Owen"],
["Cumings, Mrs. Joh"],
["Heikkinen, Miss."],
["Futrelle, Mrs. Ja"]]).toDF(["Name"])
df = df.withColumn('Surname', regexp_extract(col('Name'), '(\S+),.*', 1))
df.show()
示例数据:
+-----------------+
| Name|
+-----------------+
| Braund, Mr. Owen|
|Cumings, Mrs. Joh|
| Heikkinen, Miss.|
|Futrelle, Mrs. Ja|
+-----------------+
输出是:
+-----------------+---------+
| Name| Surname|
+-----------------+---------+
| Braund, Mr. Owen| Braund|
|Cumings, Mrs. Joh| Cumings|
| Heikkinen, Miss.|Heikkinen|
|Futrelle, Mrs. Ja| Futrelle|
+-----------------+---------+
答案 1 :(得分:0)
您可以使用regexp_extract
作为@Prem建议但使用不同的正则表达式模式,具体取决于您的需求:
# do not keep the first two groups, just what follows, the surname:
pattern = r'(?:(?:Dr|Mrs?|Ms|Miss|Master|Rev|Capt|Mlle|Col|Major|Sir|Lady|Mme|Don)\.?\s?)(\w+)'
# or keep both title and surname
pattern_with_title = r'((Dr|Mrs?|Ms|Miss|Master|Rev|Capt|Mlle|Col|Major|Sir|Lady|Mme|Don)\.?\s?)(\w+)'
#sample data
df = spark.createDataFrame([["Braund, Mr. Owen other stuff"],
["Cumings, Mrs. Joh some details"],
["Heikkinen, Miss. Hellen blah"],
["Futrelle, Mrs. Ja .... .... "]], ["Name"])
df.show()
+-----------------+
| Name|
+-----------------+
| Braund, Mr. Owen|
|Cumings, Mrs. Joh|
| Heikkinen, Miss.|
|Futrelle, Mrs. Ja|
+-----------------+
# create a column with what matches the pattern
df = df.withColumn("Surname", regexp_extract("Name", pattern, 1))
df.show()
# keeps only the Surname
+-----------------+---------+
| Name| Surname|
+-----------------+---------+
| Braund, Mr. Owen| Owen |
|Cumings, Mrs. Joh| Joh |
| Heikkinen, Miss.| Hellen |
|Futrelle, Mrs. Ja| Ja |
+-----------------+---------+
# in case you want both title and Surname:
df = df.withColumn("Surname with title", regexp_extract("Name", pattern_with_title, 1))
+-----------------+---------+--------------------+
| Name| Surname| Surname with title|
+-----------------+---------+--------------------+
|Braund, Mr. Owen | Owen | Mr. Ownen |
|Cumings, Mrs. Joh| Joh | Mrs. Joh |
|Heikkinen, Miss..| Hellen | Miss. Hellen |
|Futrelle, Mrs. Ja| Ja | Mrs. Ja |
+-----------------+---------+--------------------+
如果您需要完整的名称,标题姓氏,那么稍微改变模式以包括那些,例如:
main_pattern = r'Dr|Mrs?|Ms|Miss|Master|Rev|Capt|Mlle|Col|Major|Sir|Lady|Mme|Don'
pattern_full = r'(\w+,?\s('+ main_pattern+')\.?\s?\w+)'
pattern_name = r'(?:(?:'+ main_pattern+')\.?\s?)(\w+)'
pattern_title = r'(?:('+ main_pattern+')\.?\s?)'
pattern_surname = r'(\w+)(?:\,\s?(?:'+ main_pattern+')\.?\s?)'
df = df.withColumn("Full Name", regexp_extract("Name", pattern_full, 1))
df = df.withColumn("First Name", regexp_extract("Name", pattern_name, 1))
df = df.withColumn("Surname", regexp_extract("Name", pattern_surname, 1))
df = df.withColumn("Title", regexp_extract("Name", pattern_title, 1))
df.show(10, False)
+------------------------------+-----------------------+----------+------------+-----+
|Name |Full Name |Surname |First Name |Title|
+------------------------------+-----------------------+----------+------------+-----+
|Braund, Mr. Owen other stuff |Braund, Mr. Owen |Braund |Owen |Mr |
|Cumings, Mrs. Joh some details|Cumings, Mrs. Joh |Cumings |Joh |Mrs |
|Heikkinen, Miss. Hellen blah |Heikkinen, Miss. Hellen|Heikkinen |Hellen |Miss |
|Futrelle, Mrs. Ja .... .... |Futrelle, Mrs. Ja |Futrelle |Ja |Mrs |
+------------------------------+-----------------------+----------+------------+-----+
关于要忽略哪个部分以及在正则表达式中选择哪个部分都是关键。希望这有帮助,祝你好运!
注意:不是最佳的正则表达式,它还有改进的余地。