使用的主要操作:groupBy,pivot,sum
1.Reshaping
在某些情况下,我们可以完成重塑,如果数据量非常大,最好考虑避免完全重构的方法。
2.Pivoting数据透视
from pyspark.sql import Row
row = Row('state', 'industry', 'hq', 'jobs')
df = sc.parallelize([
row('MI', 'auto', 'domestic', 716),
row('MI', 'auto', 'foreign', 123),
row('MI', 'auto', 'domestic', 1340),
row('MI', 'retail', 'foreign', 12),
row('MI', 'retail', 'foreign', 33),
row('OH', 'auto', 'domestic', 349),
row('OH', 'auto', 'foreign', 101),
row('OH', 'auto', 'foreign', 77),
row('OH', 'retail', 'domestic', 45),
row('OH', 'retail', 'foreign', 12)
]).toDF()
df.show()
+-----+--------+--------+----+
|state|industry| hq|jobs|
+-----+--------+--------+----+
| MI| auto|domestic| 716|
| MI| auto| foreign| 123|
| MI| auto|domestic|1340|
| MI| retail| foreign| 12|
| MI| retail| foreign| 33|
| OH| auto|domestic| 349|
| OH| auto| foreign| 101|
| OH| auto| foreign| 77|
| OH| retail|domestic| 45|
| OH| retail| foreign| 12|
+-----+--------+--------+----+
数据透视操作必须总是以groupBy操作为前提。 在我们的第一个案例中,我们将简单地转向显示我们两个州中的每个州的国内和国外工作总数:
df_pivot1 = df.groupby('state').pivot('hq', values=['domestic', 'foreign']).sum('jobs')
df_pivot1.show()
+-----+--------+-------+
|state|domestic|foreign|
+-----+--------+-------+
| MI| 2056| 168|
| OH| 394| 190|
+-----+--------+-------+
请注意,pivot方法中的values = ['domestic','foreign']部分是可选的。如果我们不提供列表,PySpark将尝试通过查看透视列来推断值 指定,但自然需要更多的处理。
随着您的数据集变大,这种优化变得更加重要。 另外请注意,Spark有一个由数据透视表命令创建的10,000列限制。
df_pivot = df.groupBy('state', 'industry').pivot('hq', values=['domestic', 'foreign']).sum('jobs')
df_pivot.show()
+-----+--------+--------+-------+
|state|industry|domestic|foreign|
+-----+--------+--------+-------+
| OH| retail| 45| 12|
| MI| auto| 2056| 123|
| OH| auto| 349| 178|
| MI| retail| null| 45|
+-----+--------+--------+-------+
3.Using Pivot to Reshape Long to Wide
row = Row('state', 'industry', 'hq', 'jobs', 'firm')
df = sc.parallelize([
row('MI', 'auto', 'domestic', 716, 'A'),
row('MI', 'auto', 'foreign', 123, 'B'),
row('MI', 'auto', 'domestic', 1340, 'C'),
row('MI', 'retail', 'foreign', 12, 'D'),
row('MI', 'retail', 'foreign', 33, 'E'),
row('OH', 'retail', 'mixed', 978, 'F'),
row('OH', 'auto', 'domestic', 349, 'G'),
row('OH', 'auto', 'foreign', 101, 'H'),
row('OH', 'auto', 'foreign', 77, 'I'),
row('OH', 'retail', 'domestic', 45, 'J'),
row('OH', 'retail', 'foreign', 12, 'K'),
row('OH', 'retail', 'mixed', 1, 'L'),
row('OH', 'auto', 'other', 120, 'M'),
row('OH', 'auto', 'domestic', 96, 'A'),
row('MI', 'auto', 'foreign', 1117, 'A'),
row('MI', 'retail', 'mixed', 9, 'F'),
row('MI', 'auto', 'foreign', 11, 'B')
]).toDF()
df.show()
+-----+--------+--------+----+----+
|state|industry| hq|jobs|firm|
+-----+--------+--------+----+----+
| MI| auto|domestic| 716| A|
| MI| auto| foreign| 123| B|
| MI| auto|domestic|1340| C|
| MI| retail| foreign| 12| D|
| MI| retail| foreign| 33| E|
| OH| retail| mixed| 978| F|
| OH| auto|domestic| 349| G|
| OH| auto| foreign| 101| H|
| OH| auto| foreign| 77| I|
| OH| retail|domestic| 45| J|
| OH| retail| foreign| 12| K|
| OH| retail| mixed| 1| L|
| OH| auto| other| 120| M|
| OH| auto|domestic| 96| A|
| MI| auto| foreign|1117| A|
| MI| retail| mixed| 9| F|
| MI| auto| foreign| 11| B|
+-----+--------+--------+----+----+
df_pivot = df.groupBy('firm', 'state', 'industry').pivot('hq', values=['domestic', 'foreign', 'mixed', 'other']).sum('jobs')
df_pivot.show()
+----+-----+--------+--------+-------+-----+-----+
|firm|state|industry|domestic|foreign|mixed|other|
+----+-----+--------+--------+-------+-----+-----+
| D| MI| retail| null| 12| null| null|
| I| OH| auto| null| 77| null| null|
| G| OH| auto| 349| null| null| null|
| J| OH| retail| 45| null| null| null|
| C| MI| auto| 1340| null| null| null|
| A| MI| auto| 716| 1117| null| null|
| K| OH| retail| null| 12| null| null|
| B| MI| auto| null| 134| null| null|
| F| MI| retail| null| null| 9| null|
| E| MI| retail| null| 33| null| null|
| M| OH| auto| null| null| null| 120|
| H| OH| auto| null| 101| null| null|
| F| OH| retail| null| null| 978| null|
| L| OH| retail| null| null| 1| null|
| A| OH| auto| 96| null| null| null|
+----+-----+--------+--------+-------+-----+-----+
网友评论