【问题标题】:how to find minimum and maximum values inside collections.defaultdict如何在 collections.defaultdict 中找到最小值和最大值
【发布时间】:2021-04-09 22:51:43
【问题描述】:

美好的一天!

我正在尝试找到给定数据集的最小值和最大值

foo,1,1
foo,2,5
foo,3,0
bar,1,5
bar,2,0
bar,3,0
foo,1,1
foo,2,2
foo,3,4
bar,1,4
bar,2,0
bar,3,1
foo,1,4
foo,2,2
foo,3,3
bar,1,1
bar,2,3
bar,3,0

我尝试使用第 1 列和第 2 列作为 ID 和第 3 列作为值对我的数据进行排序

from collections import defaultdict

data = defaultdict(list)

with open("file1.txt", 'r') as infile:
    for line in infile:
        line = line.strip().split(',')
        meta = line[0]
        id_ = line[1]
        value = line[2]
        try:
            value = int(line[2])
            data[meta+id_].append(value)
        except ValueError:
            print ('nope', sep='')

我的函数的输出是:

defaultdict(list,
            {'foo1': ['1', '1', '4'],
             'foo2': ['5', '2', '2'],
             'foo3': ['0', '4', '3'],
             'bar1': ['5', '4', '1'],
             'bar2': ['0', '0', '3'],
             'bar3': ['0', '1', '0']})

请告知如何获取每个 ID 的最小值和最大值?

所以我需要这样的输出:

 defaultdict(list,
                {'foo1': ['1', '4'],
                 'foo2': ['2', '5'],
                 'foo3': ['0', '4'],
                 'bar1': ['1', '5'],
                 'bar2': ['0', '3'],
                 'bar3': ['0', '1']})

更新:

在@AndiFB 的帮助下,我将排序添加到我的列表中:

def sorting_func(string):
    return int(string)

from collections import defaultdict

data = defaultdict(list)

with open("file1.txt", 'r') as infile:
    for line in infile:
        line = line.strip().split(',')
        meta = line[0]
        id_ = line[1]
        value = line[2]
        try:
            if value != "-":
                value = int(line[2])
                data[meta+id_].append(value)
                data[meta+id_].sort(key=sorting_func)
                print("max:", *data[meta+id_][-1:], 'min:',*data[meta+id_][:1])
        except ValueError:
            print ('nope', sep='')
                        
data

输出:

max: 1 min: 1
max: 5 min: 5
max: 0 min: 0
max: 5 min: 5
max: 0 min: 0
max: 0 min: 0
max: 1 min: 1
max: 5 min: 2
max: 4 min: 0
max: 5 min: 4
max: 0 min: 0
max: 1 min: 0
max: 4 min: 1
max: 5 min: 2
max: 4 min: 0
max: 5 min: 1
max: 3 min: 0
max: 1 min: 0
defaultdict(list,
            {'foo1': [1, 1, 4],
             'foo2': [2, 2, 5],
             'foo3': [0, 3, 4],
             'bar1': [1, 4, 5],
             'bar2': [0, 0, 3],
             'bar3': [0, 0, 1]})

请告知如何只保存列表中的最小值和最大值(第一个和最后一个)?

得到这样的东西:

defaultdict(list,
                {'foo1': ['1', '4'],
                 'foo2': ['2', '5'],
                 'foo3': ['0', '4'],
                 'bar1': ['1', '5'],
                 'bar2': ['0', '3'],
                 'bar3': ['0', '1']})

【问题讨论】:

    标签: python-3.x


    【解决方案1】:

    由于您正在处理数据集,因此实现此目的的一种简单方法是使用 pandas,然后在 id 上进行 groupby 并在 values 上进行聚合以获得每个 id 的最小值和最大值

    #your question
    
    s ="""foo,1,1
    foo,2,5
    foo,3,0
    bar,1,5
    bar,2,0
    bar,3,0
    foo,1,1
    foo,2,2
    foo,3,4
    bar,1,4
    bar,2,0
    bar,3,1
    foo,1,4
    foo,2,2
    foo,3,3
    bar,1,1
    bar,2,3
    bar,3,0"""
    
    #splitting on new line
    
    t = s.split('\n')
    
    #creating datframe with comma separation
    import pandas as pd
    df = pd.DataFrame([i.split(',') for i in t])
    
    Output:
    
    >>> df
          0  1  2
    0   foo  1  1
    1   foo  2  5
    2   foo  3  0
    3   bar  1  5
    4   bar  2  0
    5   bar  3  0
    6   foo  1  1
    7   foo  2  2
    8   foo  3  4
    9   bar  1  4
    10  bar  2  0
    11  bar  3  1
    12  foo  1  4
    13  foo  2  2
    14  foo  3  3
    15  bar  1  1
    16  bar  2  3
    17  bar  3  0
    
    #creating id column by concatenating column 1 and 2, renaming column 2 as 'value' and dropping them col1 and 2
    df['id']=df[0]+df[1]
    df = df.rename(columns={df.columns[2]: 'value'})
    df = df.drop([0,1], axis = 1)
    
    Output:
    
    >>> df
       value    id
    0      1  foo1
    1      5  foo2
    2      0  foo3
    3      5  bar1
    4      0  bar2
    5      0  bar3
    6      1  foo1
    7      2  foo2
    8      4  foo3
    9      4  bar1
    10     0  bar2
    11     1  bar3
    12     4  foo1
    13     2  foo2
    14     3  foo3
    15     1  bar1
    16     3  bar2
    17     0  bar3
    
    #doing grouby and aggregating to get min and max for each id
    
    df.groupby('id').value.agg([min,max])
    
    Output:
    
         min max
    id          
    bar1   1   5
    bar2   0   3
    bar3   0   1
    foo1   1   4
    foo2   2   5
    foo3   0   4
    

    【讨论】:

    • 谢谢,但我尝试在没有熊猫的情况下完成这项任务
    【解决方案2】:
    def sorting_func(string):
        return int(string)
    
    
    d = defaultdict(list)
    d['python'].append('10')
    d['python'].append('2')
    d['python'].append('5')
    
    print("d['python'].__contains__('10'): {}".format(d['python'].__contains__('10')))
    print(str(d['python']))
    d['python'].sort(key=sorting_func)
    print('d["python"]: ' + str(d['python']))
    print('d["python"][0]: ' + d['python'][0])
    print('d["python"][2]: ' + d['python'][2])
    print(str(len(d['python'])))
    

    导致以下输出

    d['python'].__contains__('10'): True
    ['10', '2', '5']
    d["python"]: ['2', '5', '10']
    d["python"][0]: 2
    d["python"][2]: 10
    3
    

    您可以对列表进行排序,将最小值留在第一个位置,最后一个 最大值

    请注意,如果 dic 中包含的字符串不能强制转换为 Int 将导致异常。排序函数需要一个数字来比较。例如,另一个排序函数可能是:

    def sorting_func(string):
        return len(string)
    

    这个按字符串的长度排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2021-02-10
      • 2021-01-23
      • 2015-10-28
      相关资源
      最近更新 更多