csv в словарь в определенных списках (добавление значений при дублировании ключей) - PullRequest
0 голосов
/ 08 мая 2018

У меня есть CSV, как:

2018-01-31;1;2;4
2018-01-31;0;3;0
2018-02-01;5;6;7
2018-02-02;8;9;10

Моя цель - получить:

mydict = {
2018-01-31: [[1], [2,3], [4]], 
2018-02-01: [[5], [6],   [7]],
2018-03-02: [[8], [9],  [10]]
}

Обратите внимание, что при наличии «дублирующего» ключа (например, 2018-01-31) его значение должно быть добавлено к предыдущим существующим значениям для этого ключа (2,3 в примере). Редактировать : Если возможно, я не хочу добавлять 0.

Пока что самое похожее решение, которое я смог найти, это:

from collections import OrderedDict

with open('myfile.csv') as f:
    r = csv.reader(f, delimiter=";")
    od = OrderedDict()
    for row in r:
        # get key/ first element in row
        key = row[0]
    # create key/list paring if it does not exist, else just append the value
    od.setdefault(key, []).append(row[1:])

... который даже не является словарем. Я застрял на некоторое время с этим, большое спасибо заранее.

PS1: Количество строк / столбцов может различаться, но всегда будет одинаковое количество столбцов в строке

PS2: К сожалению, я не могу использовать панд

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

С помощью цикла и zip() вы можете сделать это следующим образом:

Код:

def split_data(some_data):
    results = OrderedDict()
    for datum in some_data:
        split = datum.strip().split(';')
        if split[0] in results:
            for val, dest in zip(split[1:], results[split[0]]):
                if val != '0':
                    dest.append(int(val))
        else:
            results[split[0]] = [[int(s)] for s in split[1:]]
    return results

Код теста:

from collections import OrderedDict

data = """
    2018-01-31;1;2;4
    2018-01-31;0;3;0
    2018-02-01;5;6;7
    2018-02-02;8;9;10
""".split('\n')[1:-1]

print(split_data(data))

Результаты:

OrderedDict([
    ('2018-01-31', [[1], [2, 3], [4]]), 
    ('2018-02-01', [[5], [6], [7]]), 
    ('2018-02-02', [[8], [9], [10]])
])
0 голосов
/ 08 мая 2018

Вы можете использовать itertools.groupby и zip:

import itertools, csv
with open('filename.csv') as f:
  data = list(csv.reader(f, delimiter=';'))

new_results = {a:[list(filter(None, map(int, c))) 
   for c in zip(*map(lambda x:x[1:], list(b)))]  
     for a, b in itertools.groupby(sorted(data, key=lambda x:x[0]), key=lambda x:x[0])
}

Выход:

{'2018-01-31': [[1], [2, 3], [4]], '2018-02-01': [[5], [6], [7]], '2018-02-02': [[8], [9], [10]]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...