2013-10-10 4 views
0

Таким образом, я столкнулся с некоторыми проблемами, когда беру денежный поток и пытаюсь создать чистый CF, если есть два потока денежных средств за тот же период времени.Создание чистого денежного потока

В принципе, я хочу, чтобы перейти от этого:

time=[1,2,3,3] 
cf=[100,500,1000,-500] 

к:

time=[1,2,3] 
cf=[100,500,500] 

Любые предложения, было бы полезно, как я новичок в Python. Спасибо.

+0

Будет ли «время» всегда сортироваться? –

ответ

1
from collections import defaultdict 

time=[1,2,3,3] 
cf=[100,500,1000,-500] 

result = defaultdict(int) 

for num,i in enumerate(time): 
    result[i] += cf[num] 

time2 = list(result.keys()) 
cf2 = list(result.values()) 
+0

Большое вам спасибо! Теперь я понимаю основы, но скажу, что время вытягивается в excel (время []), а cf вытягивается из соседнего столбца. Я не буду знать, есть ли повторное время или нет, есть ли способ заставить его работать таким образом? Я попытался реализовать этот метод, но он появился как обычный cf вместо cf2. –

+0

Я думаю, xlrd возвращает значения ячеек в виде строки, изменится ли это, как это сделать? –

+0

Этот метод также будет работать, если не будет повторяющихся времен. Он просто принимает значение cf и добавляет его в dict с этим ключом времени. Если повторений времени нет, он просто добавляет каждое значение cf к ключу времени один раз. Если он возвращает строковые значения, вам может потребоваться сначала перенести их в 'int()'. Проверьте [docs] (http://docs.python.org/2/library/functions.html#int) на 'int()' – Garth5689

1

Использование collections.Counter:

>>> from collections import Counter 
>>> tm = [1,2,3,3] 
>>> cf = [100,500,1000,-500] 
>>> c = Counter() 
>>> for t, ca in zip(tm, cf): 
...  c[t] += ca 
...  
>>> c 
Counter({2: 500, 3: 500, 1: 100}) 

Использование sorted и расстегивать на c.iteritems, чтобы получить ожидаемый результат:

>>> cf, tm = zip(*sorted(c.iteritems())) 
>>> cf 
(1, 2, 3) 
>>> tm 
(100, 500, 500) 

Если tm список всегда отсортирован, то вы можете также использовать itertools.groupby:

>>> from itertools import groupby, izip 
>>> tm_1 = [] 
>>> cf_1 = [] 
>>> for k, g in groupby(izip(tm, cf), key=lambda x:x[0]): 
...  tm_1.append(k) 
...  cf_1.append(sum(x[1] for x in g)) 
...  
>>> tm_1 
[1, 2, 3] 
>>> cf_1 
[100, 500, 500] 

time - это встроенный модуль, не используйте его как имя переменной.

+1

'Counter()' немного перебор; объект 'defaultdict (int)' будет заполнять ту же функцию без дополнительной функциональности, которая совершенно не входит в сферу действия здесь. –

0

Это не моя самая большая работа в стиле, но она соответствует вашим потребностям.

time=[1,2,3,3] 
cf=[100,500,1000,-500] 
transactions = zip(time, cf) 
cf = list(set(sf)) 
cf.sort() 

final_cf = [] 
for time in cf: 
    total_period = 0 
    for element in transactions: 
     if element[0] == time: 
      total_period += element[1] 
    final_cf.append(total_period) 

Другой подход использует Dict:

time=[1,2,3,3] 
cf=[100,500,1000,-500] 
transactions = zip(time, cf) 
cf_unique = list(set(cf)) 
cf_unique.sort() 
result = dict() 

for moment in cf_unique: 
result[moment] = 0 
for transaction in transactions: 
    if transaction[0] == moment: 
     result[moment] += transaction 

final_cf = result.items() 

В обоих случаях я использовал только "основные" структуры данных в Python. Я использовал набор для устранения дублированного времени, а затем сделал упорядоченный список. Затем итерация для сбора всех транзакций, которые произошли в каждом временном интервале.

Смежные вопросы