我有一個帶有 和 鍵的字典street串列。numbersome_flag
我的目標是在字典中搜索鍵street和number. 如果對于兩個或多個字典,這兩個鍵/值對是相同的,我想將值 1 分配給它們的some_flag鍵。
請參閱下面的可重現示例。
字典起始串列:
a = [
{'street': 'ocean drive', 'number': '1', 'some_flag': 0},
{'street': 'ocean drive', 'number': '3', 'some_flag': 0},
{'street': 'ocean drive', 'number': '4', 'some_flag': 0}, # duplicate street / number keys
{'street': 'ocean drive', 'number': '4', 'some_flag': 0}, # duplicate street / number keys
{'street': 'apple tree rd.', 'number': '3', 'some_flag': 0},
]
預期輸出:
a_checked = [
{'street': 'ocean drive', 'number': '1', 'some_flag': 0},
{'street': 'ocean drive', 'number': '3', 'some_flag': 0},
{'street': 'ocean drive', 'number': '4', 'some_flag': 1}, # duplicate street / number keys
{'street': 'ocean drive', 'number': '4', 'some_flag': 1}, # duplicate street / number keys
{'street': 'apple tree rd.', 'number': '3', 'some_flag': 0},
]
我的最大努力:
到目前為止我得到的代碼來自 Aarons 的答案(這里)和社區 wiki 的答案(這里)
from collections import defaultdict, Counter
items = defaultdict(list) # create defaultdict
for row in a:
items[row['street']].append(row['number']) # make a list of 'number' values for each 'street' key
for key in items.keys():
if checkIfDuplicates(items[key]): #if there is more than one 'number' --> function definition see below
duplicate_dict = {}
duplicate_dict['numbers'] = [item for item, count in Counter(items[key]).items() if count > 1] # storing duplicate numbers in dict
duplicate_dict['street'] = key # storing street name in same dict
檢查給定串列是否包含任何重復項的功能(來自此處):
def checkIfDuplicates(listOfElems):
if len(listOfElems) == len(set(listOfElems)):
return False
else:
return True
電流輸出:
print(duplicate_dict)
{'numbers': ['4'], 'street': 'ocean drive'}
使用我的方法,我現在必須將duplicate_dict與原始串列相匹配a,這似乎不是很有效。
有沒有更直接的方法來解決這個問題?
uj5u.com熱心網友回復:
您可以使用dict.setdefault首先存盤串列的字典(其中鍵是“street”和“number”),然后遍歷該字典的值以檢查多個字典是否具有相同的“street”和“number”并修改“ some_flag”中的多個:
tmp = {}
for d in a:
tmp.setdefault((d['street'], d['number']), []).append(d)
out = []
for v in tmp.values():
if len(v) > 1:
for d in v:
d['some_flag'] = 1
out.extend(v)
輸出:
[{'street': 'ocean drive', 'number': '1', 'some_flag': 0},
{'street': 'ocean drive', 'number': '3', 'some_flag': 0},
{'street': 'ocean drive', 'number': '4', 'some_flag': 1},
{'street': 'ocean drive', 'number': '4', 'some_flag': 1},
{'street': 'apple tree rd.', 'number': '3', 'some_flag': 0}]
uj5u.com熱心網友回復:
如果字典串列沒有排序,那么我們必須檢查每對可能的元素是否相等,這需要O(n^2)時間。但是如果串列是排序的,那么我們可以檢查每個元素和它的下一個元素,如果它們不相等,那么用下面的元素檢查那個元素是沒有意義的。另一方面,如果它們相等,我們繼續檢查下一個,依此類推。
def is_duplicate(d_1, d_2):
return d_1['street'] == d_2['street'] and d_1['number'] == d_2['number']
def set_duplicate(d_1, d_2):
d_1['some_flag'] = 1
d_2['some_flag'] = 1
a = sorted(a, key=lambda k: (k['street'].lower(), k['number']))
cur_index = 0
while cur_index < len(a):
next_index = cur_index 1
while next_index < len(a) and is_duplicate(a[cur_index], a[next_index]):
set_duplicate(a[cur_index], a[next_index])
next_index = 1
cur_index = 1
print(a)
uj5u.com熱心網友回復:
只需通過以下方式完成:
import pandas as pd
import numpy as np
# Your code
a = [
{'street': 'ocean drive', 'number': '1', 'some_flag': 0},
{'street': 'ocean drive', 'number': '3', 'some_flag': 0},
{'street': 'ocean drive', 'number': '4', 'some_flag': 0}, # duplicate street / number keys
{'street': 'ocean drive', 'number': '4', 'some_flag': 0}, # duplicate street / number keys
{'street': 'apple tree rd.', 'number': '3', 'some_flag': 0},
]
# My code
data = pd.DataFrame(a)
data["some_flag"]= np.where(data.duplicated(keep=False), 1, data["some_flag"])
data
輸出
| 街道 | 數字 | some_flag | |
|---|---|---|---|
| 0 | 海洋驅動器 | 1 | 0 |
| 1 | 海洋驅動器 | 3 | 0 |
| 2 | 海洋驅動器 | 4 | 1 |
| 3 | 海洋驅動器 | 4 | 1 |
| 4 | 蘋果樹路 | 3 | 0 |
如果您對使用字典而不是資料框感興趣,可以嘗試使用to_dict函式將資料框更改為字典:
data.to_dict(orient="list")
這導致:
{'number': ['1', '3', '4', '4', '3'],
'some_flag': [0, 0, 1, 1, 0],
'street': ['ocean drive',
'ocean drive',
'ocean drive',
'ocean drive',
'apple tree rd.']}
解釋
在資料框上使用duplicated函式并分配False給keep引數,您可以找到重復的行。然后使用wherewhich 是一個 numpy 函式,您可以根據邏輯陳述句為陣列賦值。
uj5u.com熱心網友回復:
您也可以在沒有 pandas 的情況下使用更多代碼來實作這一點,例如:
import copy
a = [
{'street': 'ocean drive', 'number': '1', 'some_flag': 0},
{'street': 'ocean drive', 'number': '3', 'some_flag': 0},
{'street': 'ocean drive', 'number': '4', 'some_flag': 0}, # duplicate street / number keys
{'street': 'ocean drive', 'number': '4', 'some_flag': 0}, # duplicate street / number keys
{'street': 'ocean drive', 'number': '4', 'some_flag': 0}, # duplicate street / number keys
{'street': 'ocean drive', 'number': '4', 'some_flag': 0}, # duplicate street / number keys
{'street': 'apple tree rd.', 'number': '3', 'some_flag': 0},
]
result = copy.deepcopy(a) #duplicate a to not override your input
last_entry = ""
for entry in result:
if last_entry == "": #skip first iteration to have two entries to compare
last_entry = entry
continue
if last_entry["street"] == entry["street"] and last_entry["number"] == entry["number"]:
last_entry["some_flag"] = 1
entry["some_flag"] = 1
last_entry = entry
print(result)
uj5u.com熱心網友回復:
du = {}
for d in a:
new_key = d['street'] "_" d['number']
if new_key in du.keys():
du[new_key] = du[new_key] 1
else:
du[new_key] = 1
print(du)
# {'ocean drive_1': 1, 'ocean drive_3': 1, 'ocean drive_4': 2, 'apple tree rd._3': 1}
for k, v in du.items():
if v > 1:
k1 = k.split("_")[0]
k2 = k.split("_")[1]
for d in a:
if d['street'] == k1 and d['number'] == k2:
d['some_flag'] = 1
print(a)
# [{'street': 'ocean drive', 'number': '1', 'some_flag': 0}, {'street': 'ocean drive', 'number': '3', 'some_flag': 0}, {'street': 'ocean drive', 'number': '4', 'some_flag': 1}, {'street': 'ocean drive', 'number': '4', 'some_flag': 1}, {'street': 'apple tree rd.', 'number': '3', 'some_flag': 0}]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/427803.html
上一篇:如果“.keyword”存在于串列中的特定元素中,則洗掉它
下一篇:Python:比較兩個串列中的值
