数据类型转换火花数据框列 - pyspark

Posted

技术标签:

【中文标题】数据类型转换火花数据框列 - pyspark【英文标题】:Data type casting spark data frame columns - pyspark 【发布时间】:2018-12-03 19:57:48 【问题描述】:

我在 spark DataFrame 中有一个列 ['col1','col2','col3'] 的列表,我想转换它。我尝试了以下方法,但看起来它不起作用。我确实尝试过从 DECIMAL(11,3) 数据类型转换为 DECIMAL(3,2) 和 INT

create table database_nm.test_kou
(
YEAR_MNTH_NBR        INT,
PARTN_ID             TINYINT,
EMP_NAME             STRING,
FST_AMT              DECIMAL(11,3),
SND_AMT              DECIMAL(11,3),
FST_PCT              DECIMAL(11,3),
SND_PCT              DECIMAL(11,3),
TRD_AMT              DECIMAL(11,3),
TRD_PCT              DECIMAL(11,3),
FTH_AMT              DECIMAL(11,3)
);

INSERT INTO database_nm.test_kou VALUES 
    (201812,1,'Kou',11.11,12.12,13.13,14.14,15.15,16.16,17.17);

INSERT INTO database_nm.test_kou VALUES
    (201812,1,'Cha',21.21,22.22,23.23,24.24,25.25,26.26,27.27);

INSERT INTO database_nm.test_kou VALUES 
    (201812,1,'Cha',21.21,22.22,23.23,24.24,25.25,100.00,27.27);

我的 pyspark 代码:

col_unfmt=sql("select * from database_nm.test_kou")
colWithAmt = [column for column in col_unfmt.columns if '_amt' in column]
colWithPct = [column for column in col_unfmt.columns if '_pct' in column]
colWithRemainings = [
    column for column in col_unfmt.columns if column not in colWithPct+colWithAmt
]

selectAmtColsExpr = [lit(y).cast("int").alias(y) for y in colWithAmt]
selectPctColsExpr = [(lit(z)/lit(100)).cast("decimal(3,2)").alias(z) for z in colWithPct]
selectRemainingColsExpr = colWithRemainings

col_unfmt.select(selectRemainingColsExpr+selectPctColsExpr+selectAmtColsExpr).show()
+-------------+--------+--------+-------+-------+-------+-------+-------+-------+-------+
|year_mnth_nbr|partn_id|emp_name|fst_pct|snd_pct|trd_pct|fst_amt|snd_amt|trd_amt|fth_amt|
+-------------+--------+--------+-------+-------+-------+-------+-------+-------+-------+
|       201812|       1|     Kou|   null|   null|   null|   null|   null|   null|   null|
|       201812|       1|     Cha|   null|   null|   null|   null|   null|   null|   null|
+-------------+--------+--------+-------+-------+-------+-------+-------+-------+-------+

【问题讨论】:

你为什么使用lit?看来您应该使用col 我也试过 col 但现在没有运气 当我使用 ... selectAmtColsExpr = [col(y).cast("int").alias(y) for y in colWithAmt] ... 我收到 TypeError: 'str'对象不可调用 看起来col 是你笔记本中的一个字符串。 print(type(col)) 如果它没有说 <type 'function'> 那么你有一个错误。 from pyspark.sql.functions import col 应该修复它。顺便说一句,[lit(y) for y in ...] 将返回一个列,其值等于该列的文字名称。这绝对不是你想要的。 【参考方案1】:

正如 Pault 上面建议的那样,使用 col 而不是 lit 看起来可以解决问题。

>>> selectAmtColsExpr = [col(y).cast("int") for y in colWithAmt]
>>> selectPctColsExpr = [(col(z)/100).cast("decimal(3,2)").alias(z) for z in colWithPct]
>>> selectRemainingColsExpr = colWithRemainings
col_unfmt.select(selectRemainingColsExpr+selectPctColsExpr+selectAmtColsExpr).show(20,False)
+-------------+--------+--------+-------+-------+-------+-------+-------+-------+-------+
|year_mnth_nbr|partn_id|emp_name|fst_pct|snd_pct|trd_pct|fst_amt|snd_amt|trd_amt|fth_amt|
+-------------+--------+--------+-------+-------+-------+-------+-------+-------+-------+
|201812       |1       |Kou     |0.13   |0.14   |0.16   |11     |12     |15     |17     |
|201812       |1       |Cha     |0.23   |0.24   |0.26   |21     |22     |25     |27     |
|201812       |1       |Cha     |0.23   |0.24   |1.00   |21     |22     |25     |27     |
+-------------+--------+--------+-------+-------+-------+-------+-------+-------+-------+

【讨论】:

以上是关于数据类型转换火花数据框列 - pyspark的主要内容,如果未能解决你的问题,请参考以下文章

使用圆形函数转换 pyspark 数据框列不起作用(pyspark)

将列表转换为pyspark中的数据框列

pySpark - 在插入数据库之前将整个数据框列转换为 JSON 对象

如何对 pyspark 数据框列进行向量操作?

如何将数据框列转换为数字类型?

如何将 pandas 数据框列转换为本机 python 数据类型?