#pyspark
Вопрос:
У меня есть фрейм данных, аналогичный приведенному ниже в pyspark
Имя проекта | Номер проекта |
---|---|
ТБД Канада | 10000000000029 |
TBD Китай | 10000000000033 |
TBD Соединенные Штаты | 10000000000974 |
Американский дайвер | 10000000000234 |
Цветок 2.0 | 10000000023947 |
Мне нужно извлечь страну из имени проекта, содержащего TBD. У меня также есть список названий стран из моей таблицы измерений country_list = ['Canada','United States',....., 'China']
, в этом списке около 75 стран
Сначала я попытался решить эту проблему с помощью цикла for, я написал следующее
country_list = ['Canada','United States',....., 'China']
# Set initial ExtractCountry column
df = df.withColumn("ExtractColumn", lit(None).cast("string"))
# Loop through data frame
for country in country_list:
df = df.withColumn("ExtractColumn", when(df.ProjectName.contains("TBD")
amp; df.ProjectName.contains(country), lit(country))
.otherwise(F.col("ExtractColumn")))
Это работает, но для запуска требуется очень много времени, так как мой df такой большой, и это означает, что он имеет длину фрейма данных x 75 стран. Я знаю, что в pyspark нет индексации, такой как фрейм данных pandas (я должен использовать pyspark, не могу использовать панд), но в любом случае есть ли для меня возможность просматривать фрейм данных только один раз или каким-то другим способом сократить время выполнения?
Комментарии:
1. Вам нужно распределить работу. Поместите
country_list
фрейм данных с одним столбцом страна. Затем присоединяйтесь/объединяйтесь/объединяйтесь сdf
, что приведет к масштабированию там, где цикл for этого не делает.
Ответ №1:
Вы можете просто удалить TBD
из projectname
с regexp_replace
from pyspark.sql import functions as F
(df
.withColumn('ExtractColumn', F
.when(F.col('projectname').startswith('TBD'), F.regexp_replace('projectname', 'TBD ', ''))
)
.show(10, False)
)
# Output
# ------------------ -------------- --------------
# |projectname |projectnumber |ExtractColumn |
# ------------------ -------------- --------------
# |TBD Canada |10000000000029|Canada |
# |TBD China |10000000000033|China |
# |TBD United Kingdom|10000000000033|United Kingdom|
# |US Diver |10000000000234|null |
# |Flower 2.0 |10000000023947|null |
# ------------------ -------------- --------------
Комментарии:
1. как насчет того, когда название страны состоит из более чем одного слова? есть ли способ принять все значения разделения, кроме TBD?
2. Я на самом деле думал, что разделение может быть не очень хорошей идеей, вместо этого обновил свой ответ
regex_replace
.3. не знал об этой функции. Спасибо! спаситель жизни
4. кроме того, я обновил ссылку на документ, там есть еще много функций, которые вы можете прочитать. Кроме того, не стесняйтесь принимать ответ, если вы нашли его полезным 🙂