Link 两个字典列出并计算平均值
Link two dictionaries lists and calculate average values
我不习惯用 Python 编码,但我必须用它来做这件事。我想做的是重现 SQL 语句的结果,如下所示:
SELECT T2.item, AVG(T1.Value) AS MEAN FROM TABLE_DATA T1 INNER JOIN TABLE_ITEMS T2 ON T1.ptid = T2.ptid GROUP BY T2.item.
在 Python 中,我有两个字典列表,具有公共键 'ptid'。我的 dctData 包含大约 100 000 个 pdit 和大约 7000 个 dctItems。使用像 [i for i in dctData for j in dctItems if i['ptid'] == j['ptid']]
这样的比较器是无止境的:
ptid = 1
for line in lines[6:]: # Skipping header
data = line.split()
for d in data:
dctData.append({'ptid' : ptid, 'Value': float(d)})
ptid += 1
dctData = [{'ptid':1,'Value': 0}, {'ptid':2,'Value': 2}, {'ptid':3,'Value': 2}, {'ptid':4,'Value': 5}, {'ptid':5,'Value': 3}, {'ptid':6,'Value': 2}]
for line in lines[1:]: # Skipping header
data = line.split(';')
dctItems.append({'ptid' : int(data[1]), 'item' : data[3]})
dctItems = [{'item':21, 'ptid':1}, {'item':21, 'ptid':2}, {'item':21, 'ptid':6}, {'item':22, 'ptid':2}, {'item':22, 'ptid':5}, {'item':23, 'ptid':4}]
现在,我想要得到的结果是第三个列表,它将根据 dctItems 字典中的每个项目显示平均值,而两个字典之间的 link 将基于'pdit' 值。
例如,对于项目 21,它将通过获取 ptid 1、2 和 6 的值 (0, 2, 2)
来计算 1.3 的平均值:
最后,结果看起来像这样,其中键值表示计算的平均值:
dctResults = [{'id':21, 'Value':1.3}, {'id':22, 'Value':2.5}, {'id':23, 'Value':5}]
我怎样才能做到这一点?
谢谢大家的帮助。
考虑到您使用的那些数据结构,这不是微不足道的,但如果您使用单个字典将项目映射到它们的值,它将变得 容易得多。
首先,让我们尝试以这种方式重新构建您的数据:
values = {entry['ptid']: entry['Value'] for entry in dctData}
items = {}
for item in dctItems:
items.setdefault(item['item'], []).append(values[item['ptid']])
现在,items
的形式为 {21: [0, 2, 2], 22: [2, 3], 23: [5]}
。当然,如果能在一开始就创建这种形式的字典就更好了。
现在,我们可以很容易地计算所有这些值列表的平均值:
avg = lambda lst: float(sum(lst))/len(lst)
result = {item: avg(values) for item, values in items.items()}
这样,result
就是{21: 1.3333333333333333, 22: 2.5, 23: 5.0}
或者如果您更喜欢 "list of dictionaries" 风格:
dctResult = [{'id': item, 'Value': avg(values)} for item, values in items.items()]
我不习惯用 Python 编码,但我必须用它来做这件事。我想做的是重现 SQL 语句的结果,如下所示:
SELECT T2.item, AVG(T1.Value) AS MEAN FROM TABLE_DATA T1 INNER JOIN TABLE_ITEMS T2 ON T1.ptid = T2.ptid GROUP BY T2.item.
在 Python 中,我有两个字典列表,具有公共键 'ptid'。我的 dctData 包含大约 100 000 个 pdit 和大约 7000 个 dctItems。使用像 [i for i in dctData for j in dctItems if i['ptid'] == j['ptid']]
这样的比较器是无止境的:
ptid = 1
for line in lines[6:]: # Skipping header
data = line.split()
for d in data:
dctData.append({'ptid' : ptid, 'Value': float(d)})
ptid += 1
dctData = [{'ptid':1,'Value': 0}, {'ptid':2,'Value': 2}, {'ptid':3,'Value': 2}, {'ptid':4,'Value': 5}, {'ptid':5,'Value': 3}, {'ptid':6,'Value': 2}]
for line in lines[1:]: # Skipping header
data = line.split(';')
dctItems.append({'ptid' : int(data[1]), 'item' : data[3]})
dctItems = [{'item':21, 'ptid':1}, {'item':21, 'ptid':2}, {'item':21, 'ptid':6}, {'item':22, 'ptid':2}, {'item':22, 'ptid':5}, {'item':23, 'ptid':4}]
现在,我想要得到的结果是第三个列表,它将根据 dctItems 字典中的每个项目显示平均值,而两个字典之间的 link 将基于'pdit' 值。
例如,对于项目 21,它将通过获取 ptid 1、2 和 6 的值 (0, 2, 2)
来计算 1.3 的平均值:
最后,结果看起来像这样,其中键值表示计算的平均值:
dctResults = [{'id':21, 'Value':1.3}, {'id':22, 'Value':2.5}, {'id':23, 'Value':5}]
我怎样才能做到这一点?
谢谢大家的帮助。
考虑到您使用的那些数据结构,这不是微不足道的,但如果您使用单个字典将项目映射到它们的值,它将变得 容易得多。
首先,让我们尝试以这种方式重新构建您的数据:
values = {entry['ptid']: entry['Value'] for entry in dctData}
items = {}
for item in dctItems:
items.setdefault(item['item'], []).append(values[item['ptid']])
现在,items
的形式为 {21: [0, 2, 2], 22: [2, 3], 23: [5]}
。当然,如果能在一开始就创建这种形式的字典就更好了。
现在,我们可以很容易地计算所有这些值列表的平均值:
avg = lambda lst: float(sum(lst))/len(lst)
result = {item: avg(values) for item, values in items.items()}
这样,result
就是{21: 1.3333333333333333, 22: 2.5, 23: 5.0}
或者如果您更喜欢 "list of dictionaries" 风格:
dctResult = [{'id': item, 'Value': avg(values)} for item, values in items.items()]