python:查找列表子集的最小值

时间:2016-12-06 12:43:47

标签: python-2.7

我有一个看起来像这样的列表 (列基本上是acct,subacct,value。):

1,1,3
1,2,-4
1,3,1
2,1,1
3,1,2
3,2,4
4,1,1
4,2,-1

我希望更新列表如下所示:

(列现在是每个帐户的值的acct,subacct,value,min)

1,1,3,-4
1,2,-4,-4
1,3,1,-4
2,1,1,1
3,1,2,2
3,2,4,2
4,1,1,-1
4,2,-1,-1

第四个值是通过获取每个帐户的最小值(值)得出的。因此,对于账户1,最小值为-4,因此对于与账户1相关的三个记录,col4将为-4 对于帐户2,只有一个值 对于帐户3,2和4的最小值为2,因此col 4的值为2,其中account = 3.

我需要保留col3,因为我需要稍后使用第3列中的值进行其他计算。我还需要为以后的输出创建这个附加列。

我尝试了以下内容:

with open(file_name, 'rU') as f:  #opens PW file
    data = zip(*csv.reader(f, delimiter = '\t'))

# data = list(list(rec) for rec in csv.reader(f, delimiter='\t')) 
#reads csv into a list of lists

#print the first row
uniqAcct = []
data[0] not in used and (uniqAcct.append(data[0]) or True)

但是,如果没有循环并匹配每个唯一计数然后返回并添加新列,我就会陷入困境。我认为必须有一种pythonic方式来做到这一点,但我无法弄明白。任何帮助将不胜感激!

我不能使用numpy,pandas等,因为它们还不能安装在这台服务器上。我只需要使用基本的python2

2 个答案:

答案 0 :(得分:0)

所以这里的问题是你的数据结构,索引并不容易。

理想情况下,您可以将其更改为可读的内容并将其保存在这些容器中。但是,如果你坚持要把它改成元组,我就会采用这种结构

# dummy values
data = [
    (1, 1, 3),
    (1, 2,-4),
    (1, 3, 1),
    (2, 1, 1),
    (3, 1, 2),
    (3, 2, 4),
    (4, 1, 1),
    (4, 2,-1),
]

class Account:
    def __init__(self, acct):
        self.acct      = acct
        self.subaccts  = {}    # maps sub account id to it's value

    def as_tuples(self):
        min_value = min(val for val in self.subaccts.values())

        for subacct, val in self.subaccts.items():
            yield (self.acct, subacct, val, min_value)

def accounts_as_tuples(accounts):
    return [ summary for acct_obj in accounts.values() for summary in acct_obj.as_tuples() ]

accounts = {}
for acct, subacct, val in data:
    if acct not in accounts:
        accounts[acct] = Account(acct)
    accounts[acct].subaccts[subacct] = val

print(accounts_as_tuples(accounts))

但理想情况下,我会将其保留在Account个对象中,只需添加一个方法即可在需要时提取帐户的最小值。

答案 1 :(得分:0)

这是使用初始方法的另一种方式。

修改导入数据的方式,以便在python中轻松处理。

import csv

mylist = []
with open(file_name, 'rU') as f:  #opens PW file
    data = csv.reader(f, delimiter = '\t')
    for row in data:
        splitted = row[0].split(',')
        # this is in case you need integers
        splitted = [int(i) for i in splitted]
        mylist += [splitted]

然后,添加第四列

updated = []
for acc in set(zip(*mylist)[0]):
    acclist = [x for x in mylist if x[0] == acc]
    m = min(i for sublist in acclist for i in sublist)
    [l.append(m) for l in acclist]
    updated += acclist