包含列表数据的字典,根据列表中的值进行过滤

Dictionary Containing list data, filter based on value in list

我有基于多个输入收集的测试数据,并产生单个输出。我目前将这些数据存储在字典中,其键是我的参数/结果标签,其值是测试条件和结果。我希望能够过滤数据,以便我可以根据孤立的条件生成图。

在我下面的例子中,我的测试条件是'a'和'b',实验结果是'c'。我想过滤我的数据,所以我得到一个具有相同键、值结构且只有我过滤的结果的字典。然而,我目前的字典理解 returns 是一本空字典。对获得理想结果有什么建议吗?

当前代码:

data = {'a': [0, 1, 2, 0, 1, 2], 'b': [10, 10, 10, 20, 20, 20], 'c': [1.3, 1.9, 2.3, 2.3, 2.9, 3.4]}
filtered_data = {k:v for k,v in data.iteritems() if v in data['b'] >= 20}

期望的结果:

{'a': [0, 1, 2], 'b': [20, 20, 20], 'c': [2.3, 2.9, 3.4]}

当前结果:

{}

此外,考虑到我要过滤结果,这个列表字典是否适合存储此类数据,或者是否有更好的方法来完成此操作?

考虑将 pandas 模块用于此类工作。

import pandas as pd
df = pd.DataFrame(data)
df = df[df["b"] >= 20]
print(df)

看来这会给你想要的。您正在使用字典键来表示列名,而值只是给定列中的行,因此可以使用数据框。

结果:

   a   b    c
3  0  20  2.3
4  1  20  2.9
5  2  20  3.4

是否所有字典值列表都在匹配顺序中?如果是这样,您可以只查看要过滤的列表,例如 'b' 在这种情况下,找到您想要的值,然后使用这些索引或字典中其他值的相同切片。

例如:

matching_indices = []
for i in data['b']:
    if data['b'][i] >= 20:
        matching_indices.append(i)
new_dict = {}
for key in data:
    for item in matching_indices:
        new_dict[key] = data[key][item]

如果你愿意的话,你可能会想出一个字典来理解它。希望这很清楚。

您可以将其更改为更灵活的方法。您当前的逻辑意味着数据集 a 和 c 被忽略,因为没有大于或等于 20 的值:

data = {'a': [0, 1, 2, 0, 1, 2], 'b': [10, 10, 10, 20, 20, 20], 'c': [1.3, 1.9, 2.3, 2.3, 2.9, 3.4]}
filter_vals = ['a', 'b']
new_d = {}
for k, v in data.iteritems():
  if k in filter_vals:
    new_d[k] = [i for i in v if i >= 20]

print new_d

现在我不是很多 if 语句的忠实粉丝,但像这样的东西很简单,可以多次调用

def my_filter(operator, condition, filter_vals, my_dict):
  new_d = {}
  for k, v in my_dict.iteritems():
    if k in filter_vals:
      if operator == '>':
        new_d[k] = [i for i in v if i > condition]
      elif operator == '<':
        new_d[k] = [i for i in v if i < condition]
      elif operator == '<=':
        new_d[k] = [i for i in v if i <= condition]
      elif operator == '>=':
        new_d[k] = [i for i in v if i >= condition]
  return new_d

使用这个:

k:[v[i] for i,x in enumerate(v) if data['b'][i] >= 20] for k,v in data.items()}

想要的结果:

{'a': [0, 1, 2], 'c': [2.3, 2.9, 3.4], 'b': [20, 20, 20]}

我同意上面的pandas方法。

如果您出于某种原因讨厌 pandas 或者是一位守旧的计算机科学家,元组是分解关系数据的好方法。在您的示例中,a、b 和 c 列表是列而不是行。对于元组,您希望将行存储为:

data = {'a':(0,10,1.3),'b':(1,10,1.9),'c':(2,10,2.3),'d':(0,20,2.3),'e':(1,20,2.9),'f':(2,20,3.4)}

其中元组以您描述的 (condition1, condition2, outcome) 格式存储,您可以按照您描述的方式调用单个测试或过滤一组。从那里您可以获得一组经过过滤的结果,如下所示:

filtered_data = {k:v for k,v in data.iteritems() if v[1]>=20}

哪个returns:

{'d': (0, 20, 2.3), 'e': (1, 20, 2.9), 'f': (2, 20, 3.4)}