下面是我的DF:
deviceDict = {'TABLET' : 'MOBILE', 'PHONE':'MOBILE', 'PC':'Desktop', 'CEDEX' : '', 'ST' : 'SAINT', 'AV' : 'AVENUE', 'BD': 'BOULEVARD'}
df = spark.createDataFrame([('TABLET', 'DAF ST PAQ BD'), ('PHONE', 'AVOTHA'), ('PC', 'STPA CEDEX'), ('OTHER', 'AV DAF'), (None, None)], ["device_type", 'City'])
df.show()
輸出:
----------- -------------
|device_type| City|
----------- -------------
| TABLET|DAF ST PAQ BD|
| PHONE| AVOTHA|
| PC| STPA CEDEX|
| OTHER| AV DAF|
| null| null|
----------- -------------
目的是替換鍵/值,來自Pyspark 的解決方案:通過搜索字典替換列中的值
tests = df.na.replace(deviceDict, 1)
結果:
----------- -------------
|device_type| City|
----------- -------------
| MOBILE|DAF ST PAQ BD|
| MOBILE| AVOTHA|
| Desktop| STPA CEDEX|
| OTHER| AV DAF|
| null| null|
----------- -------------
它有效,device_type但我無法更改city(即使使用子集)
預期輸出:
----------- ------------------------
|device_type| City|
----------- ------------------------
| MOBILE| DAF SAINT PAQ BOULEVARD|
| MOBILE| AVOTHA|
| Desktop| STPA|
| OTHER| AVENUE DAF|
| null| null|
----------- ------------------------
uj5u.com熱心網友回復:
該列不會發生替換,City因為您嘗試在列值中進行一些部分替換。而函式DataFrame.replace使用整個值作為映射。
要實作您想要的 column City,您可以使用多個嵌套regexp_replace運算式,您可以使用 Python 動態生成這些運算式,functools.reduce例如:
from functools import reduce
import pyspark.sql.functions as F
m = list(deviceDict.items())
df1 = df.na.replace(deviceDict, 1).withColumn(
"City",
reduce(
lambda acc, x: F.regexp_replace(acc, rf"\b{x[0]}\b", x[1]),
m[1:],
F.regexp_replace(F.col("City"), rf"\b{m[0][0]}\b", m[0][1]),
)
)
df1.show(truncate=False)
# ----------- -----------------------
#|device_type|City |
# ----------- -----------------------
#|MOBILE |DAF SAINT PAQ BOULEVARD|
#|MOBILE |AVOTHA |
#|Desktop |STPA |
#|OTHER |AVENUE DAF |
#|null |null |
# ----------- -----------------------
uj5u.com熱心網友回復:
我正在使用熊貓資料框,我認為它不會有太大不同。
您將需要使用帶有正則運算式的“ to_replace ”選項
# this will replace the old with new values given in deviceDict only if its a full string match
>>> print(deviceDict)
{'TABLET': 'MOBILE',
'PHONE': 'MOBILE',
'PC': 'Desktop',
'CEDEX': '',
'ST': 'SAINT',
'AV': 'AVENUE',
'BD': 'BOULEVARD'}
>>> print(df.replace(to_replace=deviceDict))
device_type City
0 MOBILE DAF ST PAQ BD
1 MOBILE AVOTHA
2 Desktop STPA CEDEX
3 OTHER AV DAF
4 None None
>>> df.replace(to_replace=r'\s*ST\s ', value=' SAINT ', regex = True)
device_type City
0 TABLET DAF SAINT PAQ BD
1 PHONE AVOTHA
2 PC STPA CEDEX
3 OTHER AV DAF
4 None None
>>> print(df.replace(to_replace=r'\s*AV\s ', value=' AVENUE ', regex = True))
device_type City
0 TABLET DAF ST PAQ BD
1 PHONE AVOTHA
2 PC STPA CEDEX
3 OTHER AVENUE DAF
4 None None
更通用的解決方案將是
但我認為您不想更改 AVOTHA --> AVENUEOTHA 或 STPA --> SAINTPA
如果您對該更改感到滿意,那么這將起作用
>>> print(df.replace(to_replace=deviceDict, regex=True))
device_type City
0 MOBILE DAF SAINT PAQ BOULEVARD
1 MOBILE AVENUEOTHA
2 Desktop SAINTPA
3 OTHER AVENUE DAF
4 None None
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/410206.html
標籤:
