-2

我有一个在 Pandas 中运行良好的代码片段,但是我的数据量很大,而且 Pandas 消耗了大量内存。这就是我尝试基于 PySpark 或 Koalas 的解决方案的地方,因为它们都是基于 Spark 且高度可扩展的。由于我是 Spark 的新手,我不确定如何优化这种规模的正则表达式和替换字符串。

我的代码片段:

pd_dataset['details_trunc'] = pd_dataset['details'].str.replace(r'[0-9]+GB? ', '', regex=True, flags=re.IGNORECASE).str.replace(r'[0-9]+MB?P?S? ', '', regex=True, flags=re.IGNORECASE).str.replace(r'[0-9]+\s?mins? ', '',regex=True,flags=re.IGNORECASE).str.replace(r"\(.*\)","").str.split("$").str[0].str.split('-').str[0].str.replace(r"\b[0-9]+\b", '', regex=True).str.split('fr').str[0].str.split('ends').str[0].str.split(':').str[0].str.strip()
pd_dataset['details_trunc'].replace(to_replace =r'Apple App Store.*$', value = 'Apple App Store', regex = True, inplace=True)
pd_dataset['details_trunc'].replace(to_replace =r'Google Play.*$', value = 'Google Play', regex = True, inplace=True)
pd_dataset['details_trunc'].replace('', 'NA', inplace=True)

编辑 1

在下表中,details是输入,details_trunc是输出

details_trunc 细节 班级
本地通话费 本地通话费 AAB
本地通话费 本地通话费 AAB
本地电话 本地电话 - 来电 0.00 AAB
本地电话 本地电话 - 拨出 0.00 AAB
性病电话 STD 呼叫 - E STD 020 呼叫手机号码 AAB
v019 通话 v019 通话 - 0.66 美元 AAB
v019 通话 v019 通话 - 8.80 美元 AAB
v019 通话 v019 通话 - 手机号 $0.92 AAB
v019 通话 v019 通话 - 手机号 $0.25 AAB
v019 通话 v019 通话 - 手机号 $1.84 AAB
国际直拨电话 IDD 001 通话 - E 手机号码 AAB
国际直拨电话 IDD 001 呼叫 - IDD 001 呼叫 - S AAB
漫游来电 漫游来电 193813 RRE
漫游来电 漫游来电 204459 RRE
漫游来电 漫游去电 000911 国际电话 患病的
漫游来电 漫游去电 000954 Int'l Call(S'pore) 国际线
漫游来电 漫游拨出电话 001447 国际电话(新加坡) 国际线
AutoRoam 重新路由 IDD/STD 呼叫 AutoRoam 重新路由 IDD/STD 呼叫 - AutoRoam 重新路由 IDD 呼叫 - D -(TSM:数量设置为 0,计入相应的 AutoRoam 呼叫) AAB
本地移动数据/GPRS 数据 本地移动数据/GPRS 数据(1GB = 1024MB;1MB = 1024KB) AAB
本地彩信 本地彩信 (M1/StarHub) BRQ
智能消息 SmartMessage(本地) BRQ
全球短信 全球短信 AKK
全球短信 全球短信 AKK
4

1 回答 1

-1

如果我正确理解了第一个 par 替换,您可以在 pyspark 中这样写:

from pyspark.sql import functions as F

df1 = df.withColumn(
    "details_trunc",
    F.split(
        F.regexp_replace(
            "details",
            r"[0-9]+MB?P?S? |\(.*\)|[0-9]+\s?mins? |[0-9]+GB? |\b[0-9]+\b",
            ""
        ),
        r"\-|fr|ends|:|\$"
    )[0]
)

基本上,这里的函数regexp_replace会删除所有对应的匹配项。然后split通过正则表达式使用\-|fr|ends|:|\$并获取第一个元素。

对于第二部分,您可以使用rlikeinsidewhen表达式:

df2 = df1.withColumn(
    "details_trunc",
    F.when(
        F.col("details_trunc").rlike(r'Apple App Store.*$'), 'Apple App Store'
    ).when(
        F.col("details_trunc").rlike(r'Google Play.*$'), 'Google Play'
    ).when(
        F.col("details_trunc") == '', 'NA'
    ).otherwise(F.col("details_trunc"))
)

我还没有针对所有情况对其进行测试,但这是一个很好的起点,可以帮助您将 pandas 逻辑重写为 Pyspark。

于 2021-02-19T16:40:34.590 回答