我有一個我們稱之為“會話”的字典元素串列,在每個會話中,都有一個“部分”串列、一個會話模式和時間戳:
sessions_arr = [
{'parts': [1, 2], 'session_mode': 'Driving', 'TS_start': 1632705871, 'TS_end': 1632706202},
{'parts': [3, 4], 'session_mode': 'Idling', 'TS_start': 1632706203, 'TS_end': 1632706303},
{'parts': [5, 6], 'session_mode': 'Idling', 'TS_start': 1632706304, 'TS_end': 1632706400},
{'parts': [7], 'session_mode': 'Driving', 'TS_start': 1632706401, 'TS_end': 1632706500}
]
如果連續會話具有相同的“session_mode”,則匹配會話中的部分需要合并到同一個元素中,因此我希望輸出如下所示:
sessions_arr = [
{'parts': [1, 2], 'session_mode': 'Driving', 'TS_start': 1632705871, 'TS_end': 1632706202},
{'parts': [3, 4, 5, 6], 'session_mode': 'Idling', 'TS_start': 1632706203, 'TS_end': 1632706400},
{'parts': [7], 'session_mode': 'Driving', 'TS_start': 1632706401, 'TS_end': 1632706500}
]
請注意TS_end陣列的第二個索引的 也相應地更新。我也想總是合并回來,并且只有元素是連續的。
這是我到目前為止:
for i in range(len(sessions_arr_copy) - 1):
if sessions_arr[i]['session_mode'] == sessions_arr[i 1]['session_mode']:
# if they match move that session into the one before it
sessions_arr[i]['parts'].extend(sessions_arr[i 1]['parts'])
sessions_arr[i]['TS_end'] = sessions_arr[i 1]['TS_end']
sessions_arr.pop(i 1)
此實作的問題在于,當我彈出剛合并到前一個元素中的元素時,它會更改我正在比較的串列的大小。我知道這是一個IndexError,我明白為什么會發生這個錯誤。我只想知道如何解決這個問題。我想只用一個for回圈來做到這一點,因為串列的大小可能會變得非常大,但它也不必是最快的演算法。
uj5u.com熱心網友回復:
我將把它分成兩部分:
一個知道如何合并一組字典以創建單個合并字典的函式。
itertools.groupby將串列分組到您想要的鍵上。
在一起可能看起來像:
from itertools import groupby
def merge(dicts):
merged_parts = [part for line in dicts for part in line['parts']]
start = dicts[0] ['TS_start']
end = dicts[-1]['TS_end']
return {
'parts': merged_parts,
'session_mode':dicts[0]['session_mode'],
'TS_start': start,
'TS_end': end
}
sessions_arr = [
{'parts': [1, 2], 'session_mode': 'Driving', 'TS_start': 1632705871, 'TS_end': 1632706202},
{'parts': [3, 4], 'session_mode': 'Idling', 'TS_start': 1632706203, 'TS_end': 1632706303},
{'parts': [5, 6], 'session_mode': 'Idling', 'TS_start': 1632706303, 'TS_end': 1632706400},
{'parts': [7], 'session_mode': 'Driving', 'TS_start': 1632706401, 'TS_end': 1632706500},
]
[merge(list(g)) for k, g, in groupby(sessions_arr, key=lambda d: d['session_mode'])]
這將為您留下一個新串列,如下所示:
[
{'parts': [1, 2], 'session_mode': 'Driving','TS_start': 1632705871,'TS_end': 1632706202},
{'parts': [3, 4, 5, 6], 'session_mode': 'Idling', 'TS_start': 1632706203, 'TS_end': 1632706400},
{'parts': [7], 'session_mode': 'Driving', 'TS_start': 1632706401, 'TS_end': 1632706500}
]
如果您的組很大,您可以通過不需要創建臨時檔案list(g)并使merge()函式只接受迭代器來改進這一點。
uj5u.com熱心網友回復:
當您嘗試在迭代期間更改串列時會出現問題。我會使用一個新陣列并在里面形成屬性。
sessions_arr = [
{'parts': [1, 2], 'session_mode': 'Driving', 'TS_start': 1632705871, 'TS_end': 1632706202},
{'parts': [3, 4], 'session_mode': 'Idling', 'TS_start': 1632706203, 'TS_end': 1632706303},
{'parts': [5, 6], 'session_mode': 'Idling', 'TS_start': 1632706303, 'TS_end': 1632706400},
{'parts': [7], 'session_mode': 'Driving', 'TS_start': 1632706401, 'TS_end': 1632706500}
]
helper = []
idx = 0
is_consecutive = lambda sess1, sess2: sess1['session_mode'] == sess2['session_mode']
helper.append(sessions_arr[0])
for item in sessions_arr[1:]:
if is_consecutive(helper[idx], item):
helper[idx]['parts'].extend(item['parts'])
helper[idx]['TS_end'] = item['TS_end']
else:
helper.append(item)
idx = 1
print(helper)
輸出:
[{'parts': [1, 2], 'session_mode': 'Driving', 'TS_start': 1632705871, 'TS_end': 1632706202},
{'parts': [3, 4, 5, 6], 'session_mode': 'Idling', 'TS_start': 1632706203, 'TS_end': 1632706400},
{'parts': [7], 'session_mode': 'Driving', 'TS_start': 1632706401, 'TS_end': 1632706500}]
>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/402269.html
