我有一個 Pandas 資料框,它的列包含字典。我還有一個查詢字典,我想計算公共鍵值的最小總和。
例如
dicta = {'a': 5, 'b': 21, 'c': 34, 'd': 56, 'r': 67}
dictb = {'a': 1, 'b': 1, 't': 34, 'g': 56, 'h': 67}
common keys = 'a', 'b'
s1 = dicta['a'] dicta['b']
s2 = dictb['a'] dictb['b']
result = min(s1, s2) = 2
我正在使用以下代碼來計算它。
def compute_common(dict1, dict2):
common_keys = dict1.keys() & dict2.keys()
im_count1 = sum((dict1[k] for k in common_keys))
im_count2 = sum((dict2[k] for k in common_keys))
return int(min(im_count1, im_count2))
以下是我的 i7 8 核 8GB 記憶體機器上的操作時間。
%timeit df['a'].apply(lambda x:compute_common(dictb, x))
55.2 ms ± 702 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
我還發現,我可以使用 swifter 來提高 Pandas apply 的性能(通過在內部使用多處理)
%timeit df['a'].swifter.progress_bar(False).apply(lambda x:compute_common(dictb, x))
66.4 ms ± 1.73 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
使用 swifter 甚至更慢(可能是因為多處理的開銷)。我想知道是否有任何方法可以從這個操作中榨取更多的性能。
您可以使用以下內容來復制事物。
dicta = {'a': 5, 'b': 21, 'c': 34, 'd': 56, 'r': 67}
dictb = {'a': 1, 'b': 1, 't': 34, 'g': 56, 'h': 67}
df = pd.DataFrame({'a': [dicta] * 30000})
%timeit df['a'].apply(lambda x:compute_common(dictb, x))
%timeit df['a'].swifter.progress_bar(False).apply(lambda x:compute_common(dictb, x))
提前致謝。
uj5u.com熱心網友回復:
使用串列理解來查找公共鍵的值,然后對串列結果求和,找到兩個字典和公共鍵值之間的最小值。common_keys 附加到創建 ['a','b'] 的串列中。串列推導式然后找到 a 和 b 的值并將它們相加等于 26 和 2。 26 和 2 的最小值是 2。
def find_common_keys(dicta, dictb):
'''
>>> find_common_keys({'a': 5, 'b': 21, 'c': 34, 'd': 56, 'r': 67}, {'a': 1,
'b': 1, 't': 34, 'g': 56, 'h': 67})
2
'''
common_keys = [key for key in dicta if key in dictb]
s1 = sum(dicta[key] for key in common_keys)
s2 = sum(dictb[key] for key in common_keys)
return min(s1, s2)
dicta = {'a': 5, 'b': 21, 'c': 34, 'd': 56, 'r': 67}
dictb = {'a': 1, 'b': 1, 't': 34, 'g': 56, 'h': 67}
print(find_common_keys(dicta,dictb))
輸出
2
uj5u.com熱心網友回復:
您可以將字典分解為資料框并將它們相加
dict_data = pd.DataFrame(df['a'].tolist())
common_keys = dict_data.columns.intersection(dictb.keys())
dictb_sum = sum(dictb[k] for k in common_keys)
dicta_sum = dict_data[common_keys].sum(1)
# also
output = dicta_sum.clip(upper=dictb_sum)
這比apply我的系統快兩倍。請注意,如果union(x.keys() for x in df['a'])不是太大,這會起作用,因為 的所有列都dict_data足夠大,因此您可以使用矢量化的.sum(1).
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/345057.html
