我有一个 Dataframe ,我需要通过执行以下操作在模式中做一个小的更改来创建一个新的 Dataframe 。
>>> X = spark.createDataFrame([[1,2], [3,4]], ['a', 'b'])
>>> schema_new = X.schema.add('id_col', LongType(), False)
>>> _X = X.rdd.zipWithIndex().map(lambda l: list(l[0]) + [l[1]]).toDF(schema_new)
问题是,在上面的操作中,X
的模式在原处被改变了,所以当我打印X.columns
时,我得到
>>> X.columns
['a', 'b', 'id_col']
但是X
中的值仍然相同
>>> X.show()
+---+---+
| a| b|
+---+---+
| 1| 2|
| 3| 4|
+---+---+
为了避免更改X
的模式,我尝试使用三种方法创建X
的副本-使用copy
模块中的copy
和deepcopy
方法-仅使用_X = X
copy
方法失败并返回
RecursionError: maximum recursion depth exceeded
赋值方法也不起作用
>>> _X = X
>>> id(_X) == id(X)
True
由于它们的id
是相同的,因此创建重复的 Dataframe 在这里实际上没有帮助,并且在_X
上完成的操作反映在X
中。
所以我的问题有两个
- 如何将模式更改为outplace(即不对
X
进行任何更改)? - 更重要的是,如何创建pyspark Dataframe 的副本?
- 注:**
此问题是此post的后续问题
5条答案
按热度按时间vybvopom1#
.alias()
通常用于重命名列,但它也是一个DataFrame方法,可以给予您想要的内容:mcvgt66p2#
正如在对另一个问题的回答中所解释的,你可以创建一个初始模式的深副本,然后我们可以修改这个副本,并使用它来初始化新的
DataFrame
_X
:现在让我们检查:
输出:
请注意,要复制
DataFrame
,您可以只使用_X = X
。每当您使用withColumn
添加一个新列时,对象不会在原处更改,而是返回一个新副本。希望这对您有所帮助!u0njafvf3#
如果您需要创建一个pyspark Dataframe 的副本,您可以使用Pandas(如果您的用例允许的话)。
kiayqfof4#
在Scala中:
1.使用“X.schema.copy”创建新模式示例,而不修改旧模式;
1.在每个返回Dataframe(“select”、“where”等)的Dataframe操作中,将创建新的Dataframe,而不修改原始数据。原始数据可以反复使用。猜猜看,您的情况不需要复制。性能是单独的问题,可以使用“persist”。
wn9m85ua5#
这与@SantiagoRodriguez给出的答案相同,也代表了与@tozCSS共享的类似方法。我相信@tozCSS使用
.alias()
代替.select()
的建议可能确实是最有效的。