如何在 Python 有序字典上使用 map/reduce
How to use map/reduce on Python Ordered dictionary
我有一个像这样的嵌套 python 字典:
my_dictionary = {"Ab" : {'name': 'usa', 'boolean': 'YES'},
"Ac" : {'name': 'usa', 'boolean': 'NO'},
"Ad": {'name': 'UK', 'boolean': 'NO'},
"Ae": {'name': 'UK', 'boolean': 'NO'}}
我从上面的字典创建了一个有序的字典,如下所示:
from collections import OrderedDict
sorted_dict = OrderedDict(sorted(my_dictionary.iteritems(), key=lambda x: x[1]['name']))
print sorted_dict
这给出:
OrderedDict([("Ab", {'name': 'usa', 'boolean': 'YES'}),
("Ac", {'name': 'usa', 'boolean': 'NO'}),
("Ad", {'name': 'UK', 'boolean': 'NO'}),
("Ae", {'name': 'UK', 'boolean': 'NO'})])
我需要向有序字典中添加一个新列 ('result')。创建新列的逻辑如下:
收集所有具有相同 'name' 的行:此处 'usa' 和 'UK'。然后应用基于 'boolean' 列的 reduce 方法。该函数应该是二进制的 'OR' (||).
我试过像这样应用 reduce :
reduce(lambda x,y: x['boolean'] or y['boolean']
但在选择具有相同 'name' 的所有行时卡住了。
因此最终的 Ordered 字典将如下所示:
OrderedDict([("Ab", {'name': 'usa', 'boolean': 'YES', 'result': 'YES'}),
("Ac", {'name': 'usa', 'boolean': 'NO', 'result': 'YES'}),
("Ad", {'name': 'UK', 'boolean': 'NO', 'result': 'NO'}),
("Ae", {'name': 'UK', 'boolean': 'NO', 'result': 'NO'})])
让我帮你一点点:
- 你介绍的有序字典在这里并不重要。你可以省略它并在完成你的逻辑后引入它
- 我会在一开始就将
"Yes"
转换为 True
,将 "No"
转换为 False
。让生活简单,不复杂
- 你可以不用
lambda
和 reduce
。 Python 与 any
语句一起具有列表推导式。 any
将布尔运算符 or
应用于布尔值列表。
我不确定我是否搞定了。但我希望这就是您要找的。
from functools import reduce
from itertools import groupby
def reduceByKey(func, iterable):
return map(
lambda l: (l[0], reduce(func, map(lambda p: p[1], l[1]))),
groupby(sorted(iterable, key=lambda p: p[0]), lambda p: p[0])
)
reduceByKey(
# Are you sure you want to do ("YES" or "NO") not (True or False) ?
lambda x, y: x or y
map(lambda d: yourDict[d]["name"], yourDict[d]["boolean"], yourDict)
)
yourDict
这是您的原始词典
这是一个似乎可以处理您提供的数据的方法,但我不确定这与 reduce 有什么关系。
from collections import OrderedDict, defaultdict
d = OrderedDict([("Ab", {'name': 'usa', 'boolean': 'YES'}),
("Ac", {'name': 'usa', 'boolean': 'NO'}),
("Ad", {'name': 'UK', 'boolean': 'NO'}),
("Ae", {'name': 'UK', 'boolean': 'NO'})])
def add_result(d, ikey='name', check='boolean', tt='YES', ff='NO'):
# hold results per ikey
ikey_results = defaultdict(lambda: ff)
# first pass to get results
for v in d.values():
if v[check] == tt:
ikey_results[v[ikey]] = tt
# second pass to embedd results
for v in d.values():
v['result'] = ikey_results[v[ikey]]
return d
print add_result(d)
产量
OrderedDict([('Ab', {'boolean': 'YES', 'name': 'usa', 'result': 'YES'}),
('Ac', {'boolean': 'NO', 'name': 'usa', 'result': 'YES'}),
('Ad', {'boolean': 'NO', 'name': 'UK', 'result': 'NO'}),
('Ae', {'boolean': 'NO', 'name': 'UK', 'result': 'NO'})])
这个
from pprint import pprint
my_dictionary = {"Ab": {'name': 'usa', 'boolean': True},
"Ac": {'name': 'usa', 'boolean': False},
"Ad": {'name': 'UK', 'boolean': False},
"Ae": {'name': 'UK', 'boolean': False}}
sub_result = dict()
for x in my_dictionary.values():
country_name = x['name']
sub_result[country_name ] = sub_result.get(country_name , False) or x['boolean']
new_dictionary = {k: dict(v.items() + [('result', sub_result[v['name']])]) for k, v in my_dictionary.items()}
pprint(new_dictionary)
不需要有序字典。
我有一个像这样的嵌套 python 字典:
my_dictionary = {"Ab" : {'name': 'usa', 'boolean': 'YES'},
"Ac" : {'name': 'usa', 'boolean': 'NO'},
"Ad": {'name': 'UK', 'boolean': 'NO'},
"Ae": {'name': 'UK', 'boolean': 'NO'}}
我从上面的字典创建了一个有序的字典,如下所示:
from collections import OrderedDict
sorted_dict = OrderedDict(sorted(my_dictionary.iteritems(), key=lambda x: x[1]['name']))
print sorted_dict
这给出:
OrderedDict([("Ab", {'name': 'usa', 'boolean': 'YES'}),
("Ac", {'name': 'usa', 'boolean': 'NO'}),
("Ad", {'name': 'UK', 'boolean': 'NO'}),
("Ae", {'name': 'UK', 'boolean': 'NO'})])
我需要向有序字典中添加一个新列 ('result')。创建新列的逻辑如下:
收集所有具有相同 'name' 的行:此处 'usa' 和 'UK'。然后应用基于 'boolean' 列的 reduce 方法。该函数应该是二进制的 'OR' (||).
我试过像这样应用 reduce :
reduce(lambda x,y: x['boolean'] or y['boolean']
但在选择具有相同 'name' 的所有行时卡住了。
因此最终的 Ordered 字典将如下所示:
OrderedDict([("Ab", {'name': 'usa', 'boolean': 'YES', 'result': 'YES'}),
("Ac", {'name': 'usa', 'boolean': 'NO', 'result': 'YES'}),
("Ad", {'name': 'UK', 'boolean': 'NO', 'result': 'NO'}),
("Ae", {'name': 'UK', 'boolean': 'NO', 'result': 'NO'})])
让我帮你一点点:
- 你介绍的有序字典在这里并不重要。你可以省略它并在完成你的逻辑后引入它
- 我会在一开始就将
"Yes"
转换为True
,将"No"
转换为False
。让生活简单,不复杂 - 你可以不用
lambda
和reduce
。 Python 与any
语句一起具有列表推导式。any
将布尔运算符or
应用于布尔值列表。
我不确定我是否搞定了。但我希望这就是您要找的。
from functools import reduce
from itertools import groupby
def reduceByKey(func, iterable):
return map(
lambda l: (l[0], reduce(func, map(lambda p: p[1], l[1]))),
groupby(sorted(iterable, key=lambda p: p[0]), lambda p: p[0])
)
reduceByKey(
# Are you sure you want to do ("YES" or "NO") not (True or False) ?
lambda x, y: x or y
map(lambda d: yourDict[d]["name"], yourDict[d]["boolean"], yourDict)
)
yourDict
这是您的原始词典
这是一个似乎可以处理您提供的数据的方法,但我不确定这与 reduce 有什么关系。
from collections import OrderedDict, defaultdict
d = OrderedDict([("Ab", {'name': 'usa', 'boolean': 'YES'}),
("Ac", {'name': 'usa', 'boolean': 'NO'}),
("Ad", {'name': 'UK', 'boolean': 'NO'}),
("Ae", {'name': 'UK', 'boolean': 'NO'})])
def add_result(d, ikey='name', check='boolean', tt='YES', ff='NO'):
# hold results per ikey
ikey_results = defaultdict(lambda: ff)
# first pass to get results
for v in d.values():
if v[check] == tt:
ikey_results[v[ikey]] = tt
# second pass to embedd results
for v in d.values():
v['result'] = ikey_results[v[ikey]]
return d
print add_result(d)
产量
OrderedDict([('Ab', {'boolean': 'YES', 'name': 'usa', 'result': 'YES'}),
('Ac', {'boolean': 'NO', 'name': 'usa', 'result': 'YES'}),
('Ad', {'boolean': 'NO', 'name': 'UK', 'result': 'NO'}),
('Ae', {'boolean': 'NO', 'name': 'UK', 'result': 'NO'})])
这个
from pprint import pprint
my_dictionary = {"Ab": {'name': 'usa', 'boolean': True},
"Ac": {'name': 'usa', 'boolean': False},
"Ad": {'name': 'UK', 'boolean': False},
"Ae": {'name': 'UK', 'boolean': False}}
sub_result = dict()
for x in my_dictionary.values():
country_name = x['name']
sub_result[country_name ] = sub_result.get(country_name , False) or x['boolean']
new_dictionary = {k: dict(v.items() + [('result', sub_result[v['name']])]) for k, v in my_dictionary.items()}
pprint(new_dictionary)
不需要有序字典。