[英]Stack table by Pyspark SQL
我想使用看起来像这样的火花将它们堆叠起来。
+-----------+--------+-----+
|CountryName|variable|value|
+-----------+--------+-----+
| Aruba| 1960| NaN|
| Aruba| 1961| NaN|
| Aruba| 1962| NaN|
| Aruba| 1963| NaN|
| Aruba| 1964| NaN|
| Aruba| 1965| NaN|
| Aruba| 1966| NaN|
| Aruba| 1967| NaN|
| Aruba| 1968| NaN|
| Aruba| 1969| NaN|
| Aruba| 1970| NaN|
| Aruba| 1971| NaN|
| Aruba| 1972| NaN|
| Aruba| 1973| NaN|
| Aruba| 1974| NaN|
| Aruba| 1975| NaN|
| Aruba| 1976| NaN|
| Aruba| 1977| NaN|
| Aruba| 1978| NaN|
| Aruba| 1979| NaN|
+-----------+--------+-----+
但出于某种原因,我一直在获取此表,其中第 4 列的值与第 3 列的值相同。 我还有其他办法吗?
+-----------+-----------+----+-----------+
|CountryName|CountryCode|Year|CO2Emission|
+-----------+-----------+----+-----------+
| Aruba| ABW|1960| 1960|
| Aruba| ABW|1961| 1961|
| Aruba| ABW|1962| 1962|
| Aruba| ABW|1963| 1963|
| Aruba| ABW|1964| 1964|
| Aruba| ABW|1965| 1965|
| Aruba| ABW|1966| 1966|
| Aruba| ABW|1967| 1967|
| Aruba| ABW|1968| 1968|
| Aruba| ABW|1969| 1969|
| Aruba| ABW|1970| 1970|
| Aruba| ABW|1971| 1971|
| Aruba| ABW|1972| 1972|
| Aruba| ABW|1973| 1973|
| Aruba| ABW|1974| 1974|
| Aruba| ABW|1975| 1975|
| Aruba| ABW|1976| 1976|
| Aruba| ABW|1977| 1977|
| Aruba| ABW|1978| 1978|
| Aruba| ABW|1979| 1979|
+-----------+-----------+----+-----------+
这是我的代码:
spark.sql("""
select CountryName, CountryCode, stack(55,'1960',1960,'1961',1961,'1962',1962,'1963',1963,'1964',1964,'1965',1965,'1966',1966,'1967',1967,'1968',1968,'1969',1969,
'1970',1970,'1971',1971,'1972',1972,'1973',1973,'1974',1974,'1975',1975,'1976',1976,'1977',1977,'1978',1978,'1979',1979,
'1980',1980,'1981',1981,'1982',1982,'1983',1983,'1984',1984,'1985',1985,'1986',1986,'1987',1987,'1988',1988,'1989',1989,
'1990',1990,'1991',1991,'1992',1992,'1993',1993,'1994',1994,'1995',1995,'1996',1996,'1997',1997,'1998',1998,'1999',1999,
'2000',2000,'2001',2001,'2002',2002,'2003',2003,'2004',2004,'2005',2005,'2006',2006,'2007',2007,'2008',2008,'2009',2009,'2010',
2010,'2011',2011,'2012',2012,'2013',2013,'2014',2014 ) as (Year, CO2Emission)
from CO2level
""").show()
请帮我。 我对 Spark 非常陌生。 我稍后需要将它与另一张桌子一起加入所以请告诉我!
使用create_map和explode函数可以轻松完成:
import pyspark.sql.functions as f
df = spark.read.table("CO2level")
df = df.withColumn(
"other_cols",
f.create_map(*[col for col in df.columns if col != "CountryName"])
)
df = df.select("CountryName", f.explode("other_cols").alias("variable","value"))
df.show(truncate=False)
CO2Emission
的值与Year
完全相同的原因是因为您的列名称是数字(例如 1960、1961 等),因此在堆叠'1960',1960
时,您将字符串'1960'
堆叠在integer 1960
之上。 修复它的最简单方法是将 integer 列名包装在一对反引号``中,例如“'1960','1960'”。
df = spark.createDataFrame([
('C1', 'c1', 1, 2, 3),
('C2', 'c2', 4, 5, 6),
('C3', 'c3', 7, 8, 9),
], ['name', 'code', '1960', '1961', '1962'])
+----+----+----+----+----+
|name|code|1960|1961|1962|
+----+----+----+----+----+
| C1| c1| 1| 2| 3|
| C2| c2| 4| 5| 6|
| C3| c3| 7| 8| 9|
+----+----+----+----+----+
(df
.select('name', 'code', F.expr('stack(3, "1960", `1960`, "1961", `1961`, "1962", `1962`)'))
.show()
)
+----+----+----+----+
|name|code|col0|col1|
+----+----+----+----+
| C1| c1|1960| 1|
| C1| c1|1961| 2|
| C1| c1|1962| 3|
| C2| c2|1960| 4|
| C2| c2|1961| 5|
| C2| c2|1962| 6|
| C3| c3|1960| 7|
| C3| c3|1961| 8|
| C3| c3|1962| 9|
+----+----+----+----+
您可能已经意识到带有所有硬编码列的长select
没有任何好处,更不用说模式可能会更改并且可能会发生错误。 您可以使用 for 循环来获取列名并构建一个字符串,而不是将它们写下来。
cols = [f'"{c}", `{c}`' for c in df.columns if c not in ['name', 'code']]
# ['"1960", `1960`', '"1961", `1961`', '"1962", `1962`']
(df
.select('name', 'code', F.expr(f'stack({len(cols)}, {",".join(cols)})'))
.show()
)
+----+----+----+----+
|name|code|col0|col1|
+----+----+----+----+
| C1| c1|1960| 1|
| C1| c1|1961| 2|
| C1| c1|1962| 3|
| C2| c2|1960| 4|
| C2| c2|1961| 5|
| C2| c2|1962| 6|
| C3| c3|1960| 7|
| C3| c3|1961| 8|
| C3| c3|1962| 9|
+----+----+----+----+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.