我有一个像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:不幸的是我无法使用Pandas
答案 0 :(得分:2)
您可以使用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]]}
答案 1 :(得分:2)
使用循环和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]])
])