字典包含列表数据,根据列表

时间:2016-05-31 15:22:07

标签: python list dictionary dictionary-comprehension

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

在下面的例子中,我的测试条件是'a'和'b',实验结果将是'c'。我想过滤我的数据,所以我得到一个具有相同键,值结构的字典,只有我的过滤结果。但是我当前的字典理解返回一个空字典。有什么建议可以得到理想的结果吗?

当前代码:

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]}

当前结果:

{}

另外,这个列表字典是一个很好的架构来存储这种类型的数据,因为我想要过滤结果,还是有更好的方法来实现这个?

5 个答案:

答案 0 :(得分:3)

考虑将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

答案 1 :(得分:3)

使用它:

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]}

答案 2 :(得分:0)

匹配订单中的所有字典值列表都是?如果是这样,您可以查看要过滤的列表,在这种情况下说'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]

如果你愿意,你可能会想到它的字典理解。希望这很清楚。

答案 3 :(得分:0)

您可以将其更改为一种可以提供更大灵活性的方法。您当前的逻辑意味着数据集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

答案 4 :(得分:0)

我同意上面的熊猫方法。

如果由于某种原因你讨厌大熊猫或者是一个老学校的计算机科学家,那么元组是一种撕裂关系数据的好方法。在您的示例中,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}

返回:

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