Python 拆分、合并、排序CSV
我有几个CSV文件,其中包含来自几个传感器的测量值 s1.CSV:Python 拆分、合并、排序CSV,python,python-2.7,Python,Python 2.7,我有几个CSV文件,其中包含来自几个传感器的测量值 s1.CSV: date;hour;source;values 01/25/12;10:20:00;a; 88 -84 27 01/25/12;10:30:00;a; -80 01/25/12;10:50:00;b; -96 3 -88 01/25/12;09:00:00;b; -97 101 01/25/12;09:10:00;c; 28 s2.CSV: date;hour;source;values 01/25/12;10:20:00;a
date;hour;source;values
01/25/12;10:20:00;a; 88 -84 27
01/25/12;10:30:00;a; -80
01/25/12;10:50:00;b; -96 3 -88
01/25/12;09:00:00;b; -97 101
01/25/12;09:10:00;c; 28
s2.CSV:
date;hour;source;values
01/25/12;10:20:00;a; 133
01/25/12;10:25:00;a; -8 -5
我想按来源(a/b/c)创建一个CSV,每个度量值在单独的列中,按日期和小时排序
a、 CSV:
date;hour;source;s1;s2
01/25/12;10:20:00;a; 88 -84 27; 133
01/25/12;10:25:00;a; ; -8 -5
01/25/12;10:30:00;a; -80;
我被困在这里:
import glob
import csv
import os
os.system('cls')
sources = dict()
sensor = 0
filelist = glob.glob("*.csv")
for f in filelist:
reader = csv.DictReader(open(f),delimiter=";")
for row in reader:
# date = row['date'] # date later
hour = row['hour']
val = row['values']
source = row['source']
if not sources.has_key(source): # new source
sources[source] = list()
#
sources[source].append({'hour':hour, 'sensor'+`sensor`:val})
sensor+=1
我不确定数据结构是否适合排序。我也喜欢重复列名 根据你提供的数据,我用熊猫做了一些东西。请参阅下面的代码 由于
hour
和source
在一列中重复,因此输出是不理想的。当我也在学习的时候,我也欢迎任何关于熊猫是否能达到OP要求的专家意见
In [1]: import pandas as pd
In [2]: s1 = pd.read_csv('s1.csv', delimiter=';', parse_dates=True)
In [3]: s1
Out[3]:
date hour source values
0 01/25/12 10:20:00 a 88 -84 27
1 01/25/12 10:30:00 a -80
2 01/25/12 10:50:00 b -96 3 -88
3 01/25/12 09:00:00 b -97 101
4 01/25/12 09:10:00 c 28
In [4]: s2 = pd.read_csv('s2.csv', delimiter=';', parse_dates=True)
In [5]: s2
Out[5]:
date hour source values
0 01/25/12 10:20:00 a 133
1 01/25/12 10:25:00 a -8 -5
In [6]: joined = s1.append(s2)
In [7]: joined
Out[7]:
date hour source values
0 01/25/12 10:20:00 a 88 -84 27
1 01/25/12 10:30:00 a -80
2 01/25/12 10:50:00 b -96 3 -88
3 01/25/12 09:00:00 b -97 101
4 01/25/12 09:10:00 c 28
0 01/25/12 10:20:00 a 133
1 01/25/12 10:25:00 a -8 -5
In [8]: grouped = joined.groupby('hour').sum()
In [9]: grouped.to_csv('a.csv')
In [10]: grouped
Out[10]:
date source values
hour
09:00:00 01/25/12 b -97 101
09:10:00 01/25/12 c 28
10:20:00 01/25/1201/25/12 aa 88 -84 27 133
10:25:00 01/25/12 a -8 -5
10:30:00 01/25/12 a -80
10:50:00 01/25/12 b -96 3 -88
根据你提供的数据,我用熊猫做了一些东西。请参阅下面的代码 由于
hour
和source
在一列中重复,因此输出是不理想的。当我也在学习的时候,我也欢迎任何关于熊猫是否能达到OP要求的专家意见
In [1]: import pandas as pd
In [2]: s1 = pd.read_csv('s1.csv', delimiter=';', parse_dates=True)
In [3]: s1
Out[3]:
date hour source values
0 01/25/12 10:20:00 a 88 -84 27
1 01/25/12 10:30:00 a -80
2 01/25/12 10:50:00 b -96 3 -88
3 01/25/12 09:00:00 b -97 101
4 01/25/12 09:10:00 c 28
In [4]: s2 = pd.read_csv('s2.csv', delimiter=';', parse_dates=True)
In [5]: s2
Out[5]:
date hour source values
0 01/25/12 10:20:00 a 133
1 01/25/12 10:25:00 a -8 -5
In [6]: joined = s1.append(s2)
In [7]: joined
Out[7]:
date hour source values
0 01/25/12 10:20:00 a 88 -84 27
1 01/25/12 10:30:00 a -80
2 01/25/12 10:50:00 b -96 3 -88
3 01/25/12 09:00:00 b -97 101
4 01/25/12 09:10:00 c 28
0 01/25/12 10:20:00 a 133
1 01/25/12 10:25:00 a -8 -5
In [8]: grouped = joined.groupby('hour').sum()
In [9]: grouped.to_csv('a.csv')
In [10]: grouped
Out[10]:
date source values
hour
09:00:00 01/25/12 b -97 101
09:10:00 01/25/12 c 28
10:20:00 01/25/1201/25/12 aa 88 -84 27 133
10:25:00 01/25/12 a -8 -5
10:30:00 01/25/12 a -80
10:50:00 01/25/12 b -96 3 -88
如果我理解正确,您有多个文件,每个文件对应一个给定的“传感器”,文件名中有传感器的标识。您希望读取文件,然后再次将其写入单独的文件中,这次按“源”划分,将来自不同传感器的数据合并成最后几行 以下是我认为你想要做的:
'a'
)(日期、时间)
元组键入from collections import defaultdict
from datetime import datetime
import csv
import glob
import os
# data structure is data[source][date, time][sensor] = value, with "" as default value
data = defaultdict(lambda: defaultdict(lambda: defaultdict(str)))
sensors = []
filelist = glob.glob("*.csv")
# read old files
for fn in filelist:
sensor = os.path.splitext(fn)[0]
sensors.append(sensor)
with open(fn, 'rb') as f:
reader = csv.DictReader(f, delimiter=";")
for row in reader:
date = datetime.strptime(row['date'], '%m/%d/%y')
data[row['source']][date, row['hour']][sensor] = row['values']
sensors.sort() # note, this may not give the best sort order
header = ['date', 'hour', 'source'] + sensors
for source, source_data in data.iteritems():
fn = "{}.csv".format(source)
with open(fn, 'wb') as f:
writer = csv.writer(f, delimiter=";")
writer.writerow(header)
for (date, time), hour_data in sorted(source_data.items()):
values = [hour_data[sensor] for sensor in sensors]
writer.writerow([date.strftime('%m/%d/%y'), time, source] + values)
我只将日期字段转换为内部类型,因为否则基于日期的排序将无法正常工作(2013年1月的日期将出现在2012年2月的日期之前)。在未来,考虑使用ISO 8601风格的日期格式,<代码> YYY-MM-DD ,它可以被安全地排序为字符串。其余的值仅作为字符串处理,没有解释
代码假定传感器的值可以按字典顺序排列。如果您只有其中的几个,例如s1
和s2
,则可能出现这种情况。但是,如果您有一个s10
,它将被排序在s2
之前。要解决这个问题,你需要一个“自然”排序,这比我在这里能解决的更复杂(但更多信息请参阅)
最后一个警告:如果您在同一个文件夹中多次运行此解决方案,则可能会产生不良后果。这是因为当您再次运行时,
glob.glob('*.csv')
会将输出文件(例如a.csv
)视为输入文件。如果我理解正确,您有多个文件,每个文件对应于给定的“传感器”,文件名中有传感器的标识。您希望读取文件,然后再次将其写入单独的文件中,这次按“源”划分,将来自不同传感器的数据合并成最后几行
以下是我认为你想要做的:
'a'
)(日期、时间)
元组键入from collections import defaultdict
from datetime import datetime
import csv
import glob
import os
# data structure is data[source][date, time][sensor] = value, with "" as default value
data = defaultdict(lambda: defaultdict(lambda: defaultdict(str)))
sensors = []
filelist = glob.glob("*.csv")
# read old files
for fn in filelist:
sensor = os.path.splitext(fn)[0]
sensors.append(sensor)
with open(fn, 'rb') as f:
reader = csv.DictReader(f, delimiter=";")
for row in reader:
date = datetime.strptime(row['date'], '%m/%d/%y')
data[row['source']][date, row['hour']][sensor] = row['values']
sensors.sort() # note, this may not give the best sort order
header = ['date', 'hour', 'source'] + sensors
for source, source_data in data.iteritems():
fn = "{}.csv".format(source)
with open(fn, 'wb') as f:
writer = csv.writer(f, delimiter=";")
writer.writerow(header)
for (date, time), hour_data in sorted(source_data.items()):
values = [hour_data[sensor] for sensor in sensors]
writer.writerow([date.strftime('%m/%d/%y'), time, source] + values)
我只将日期字段转换为内部类型,因为否则基于日期的排序将无法正常工作(2013年1月的日期将出现在2012年2月的日期之前)。在未来,考虑使用ISO 8601风格的日期格式,<代码> YYY-MM-DD ,它可以被安全地排序为字符串。其余的值仅作为字符串处理,没有解释
代码假定传感器的值可以按字典顺序排列。如果您只有其中的几个,例如s1
和s2
,则可能出现这种情况。但是,如果您有一个s10
,它将被排序在s2
之前。要解决这个问题,你需要一个“自然”排序,这比我在这里能解决的更复杂(但更多信息请参阅)
最后一个警告:如果您在同一个文件夹中多次运行此解决方案,则可能会产生不良后果。这是因为当您再次运行时,
glob.glob('*.csv')
会将输出文件(例如a.csv
)视为输入文件。请不要吝惜您的第一次尝试!你想学习,对吗?让我们帮助您改进您自己的努力。更重要的是,如果您不向我们展示您的尝试,这个问题将不得不结束,因为您不会“展示对正在解决的问题的最低理解”。是的,请发布您的想法,因为这更像是编辑的动机,而不是从头开始创建。除非你只是想要伪代码(“创建一个以时间为键的字典…”),否则我建议使用Pandas Package