如何正确使用reduce和字典
Posted
技术标签:
【中文标题】如何正确使用reduce和字典【英文标题】:How to properly use reduce with a dictionary 【发布时间】:2020-05-21 06:10:56 【问题描述】:我正在使用自定义函数作为 reduce 操作的一部分。对于以下示例,我收到以下消息 TypeError: reduce() takes no keyword arguments
- 我相信这是由于我在函数 mapping
中使用字典 exposed_colum
的方式 - 你能帮我修复这个函数吗?
from pyspark.sql import DataFrame, Row
from pyspark.sql.functions import col
from pyspark.sql import SparkSession
from functools import reduce
def process_data(df: DataFrame):
col_mapping = dict(zip(["name", "age"], ["a", "b"]))
# Do other things...
def exposed_column(df: DataFrame, mapping: dict):
return df.select([col(c).alias(mapping.get(c, c)) for c in df.columns])
return reduce(exposed_column, sequence=col_mapping, initial=df)
spark = SparkSession.builder.appName("app").getOrCreate()
l = [
("Bob", 25, "Spain"),
("Marc", 22, "France"),
("Steve", 20, "Belgium"),
("Donald", 26, "USA"),
]
rdd = spark.sparkContext.parallelize(l)
people = rdd.map(lambda x: Row(name=x[0], age=int(x[1]), country=x[2])).toDF()
people.show()
process_data(people).show()
people.show()
看起来像这样
+---+-------+------+
|age|country| name|
+---+-------+------+
| 25| Spain| Bob|
| 22| France| Marc|
| 20|Belgium| Steve|
| 26| USA|Donald|
+---+-------+------+
这是预期的输出
+------+---+
| a| b|
+------+---+
| Bob| 25|
| Marc| 22|
| Steve| 20|
|Donald| 26|
+------+---+
【问题讨论】:
你能检查一下 people.show() 吗? 当然,我刚刚在问题中添加了show()
语句
【参考方案1】:
reduce
不带关键字,这是真的。
一旦你删除了关键字,你会注意到一个更严重的问题:当你迭代一个字典时,你只是在迭代它的键。因此,您尝试批量重命名列的函数不会按照您的想法进行。
批量重命名列的一种方法是遍历字典的items
:
from typing import Mapping
from pyspark.sql import DataFrame
def rename_columns(frame: DataFrame, mapping: Mapping[str, str]) -> DataFrame:
return reduce(lambda f, old_new: f.withColumnRenamed(old_new[0], old_new[1]),
mapping.items(), frame)
这允许您传入一个字典(注意the recommendation 用于向参数添加类型提示是使用Mapping
,而不是dict
)将列名映射到其他名称。幸运的是,如果您尝试重命名不在 DataFrame
中的列,withColumnRenamed
不会抱怨,因此这相当于您的 mapping.get(c, c)
。
我在您的代码中没有注意到的一件事是它正在删除 country
列。所以这仍然会在你的输出中。
【讨论】:
以上是关于如何正确使用reduce和字典的主要内容,如果未能解决你的问题,请参考以下文章
如何正确使用 TypeScript 和 Array.prototype.reduce?
Swift - 使用 map/reduce/flatmap 将数组字典减少为相同类型的单个数组