我的计算机上的文档中有多个数据框(csv文件)位于各种文件夹中。所有csv文件具有相同的列数,其中每列的名称相同且顺序相同,但是,文件中存在不同数量的数据行。所有文件都有"日期时间"作为他们的第一栏,其中" YYYYMMDD HH:MM:SS"记录下来的数据行。
我想重新采样所有数据框,以便从原始文件创建每小时,每日和每月数据。 csv文件中的某些列要求数据在小时,日和月中求和,而其他列需要在这些时间帧上对数据求平均值(在所有csv文件中保持一致)。我希望每个原始csv文件都有自己的每小时,每日和每月版本。
所有csv文件都存在于以下inputpath中,但实际上位于此inputpath中的其他文件中:
inputpath =' C:/ Users / cp_vm / Documents / Data / Input / Clean /'
例如,在文件夹" Clean"还有两个文件夹,其中包含所有csv文件。我想读取所有存在于" Clean"之后的csv文件。文件夹,无需编写多个输入路径'并如前所述重新取样文件。
然后,我想将这些重新采样的数据框导出到它们来自的文件夹,并添加"小时","日"或"月"他们的名字。
下面提供了csv文件的代码段示例。
例如,我想将15分钟间隔数据重新采样为每小时,每日和每月数据。重采样时需要对前两列求和,而第三列需要在重采样时间帧上求平均值。我知道df.resample(' h')。sum()将对小时内的数据求和,而.mean()将平均一小时内的数据,但是当不同列需要不同时,它很棘手重新采样,然后想要将所有这些列组合在一起,然后将每小时,每日或每月文件导出到文件名已自动更改的相应位置,以显示它现在是每小时,每天或每月。
我意识到这是非常具有描述性的,但它导致了各种延迟并重新定位csv文件将影响我已编写过的另一个python脚本。任何建议将不胜感激。提前感谢您提供的任何帮助。
答案 0 :(得分:0)
很难找到问题的确切位置:)
但是python有类似os.walk的东西,让我举个例子:
import os
root_directory = '/home/xyz/some_root_dir/'
def is_csv(fname):
return fname.endswith('.csv')
csv_files = []
for directory, subdirectories, files_names in os.walk(root_directory):
for fname in files_names:
if is_csv(fname):
csv_files.append(
{
'directory': directory,
'fname': fname
}
)
print(csv_files)
这在我的测试用例中:
[
{'directory': '/home/xyz/some_root_dir', 'fname': 'my.csv'},
{'directory': '/home/xyz/some_root_dir/test2/test31', 'fname': 'myohter3.csv'}
{'directory': '/home/xyz/some_root_dir/test2/test31', 'fname': 'myohter.csv'}
]
这肯定会帮助您获取所有csv文件 - 您可以根据需要修改is_csv方法。我无法帮助您汇总数据:)
但是一旦你阅读了所有的数据,这应该不是什么大问题。
好的,现在开始有趣了。我做得非常快 - 可能写得更好,但这是一个很好的起点,我们有上一步的文件列表,让我们做下一步:
import csv
import os
from datetime import datetime
data = {}
# gather the data;
for fdata in csv_files:
with open(os.path.join(fdata['directory'], fdata['fname']), 'r') as f:
reader = csv.reader(f, delimiter='|', quotechar='"')
rows = list(reader)
data[fdata['fname']] = rows # we can't store it per datetime here, because can lost data
# ok we have a data now in format:
# {
# 'other3.csv': [
# ['Datetime', 'Egen1_NotCum_kWh', 'Egen2_NotCum_kWh', 'Egen3_NotCum_kWh'],
# ['2016-09-04 13:45:00', '643.23', '649', '654'],
# ['2016-09-04 14:00:00', '612.21', '672', '666'],
# ['2016-09-04 14:15:00', '721.3', '719', '719'],
# ['2016-09-04 14:30:00', '730', '721', '725'],
# ['2016-09-04 14:45:00', '745', '725', '731']],
# 'my.csv': ...
# }
# convert the string data to python Datetime
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
for fname, inner_data in data.iteritems():
for row in inner_data[1:]: # skip headers
p_datetime = datetime.strptime(row[0], DATETIME_FORMAT)
row[0] = p_datetime
# now the aggregates;
def get_all_rows_in_dates(start_date, end_date, data):
headers = data[data.keys()[0]][0]
data_rows = []
for fname, inner_data in data.iteritems():
for row in inner_data[1:]: # skip the header
if start_date <= row[0] < end_date:
data_rows.append(row)
return headers, data_rows
def aggregate_col_12(values):
values = map(float, values)
return sum(values)
def aggregate_col_3(values):
values = map(float, values)
return sum(values) / float(len(values))
def count_aggregates(rows_in_dates, start_date):
col1 = []
col2 = []
col3 = []
for row in rows_in_dates[1:]: # skip headers
col1.append(row[1])
col2.append(row[2])
col3.append(row[3])
return [start_date.strftime(DATETIME_FORMAT),
aggregate_col_12(col1), aggregate_col_12(col2), aggregate_col_3(col3)]
def write_results(headers, aggregate, fname):
data = []
data.append(headers)
data.append(aggregate)
with open(fname, 'w+') as f:
writer = csv.writer(f, delimiter='|', quotechar='"', quoting=csv.QUOTE_MINIMAL)
writer.writerows(data)
start_date = datetime(2016, 9, 4, 13, 0, 0)
end_date = datetime(2016, 9, 4, 14, 0, 0)
headers, to_aggregate = get_all_rows_in_dates(
start_date,
end_date,
data)
aggregates = count_aggregates(to_aggregate, start_date)
write_results(headers, aggregates, 'from_{}_to_{}.csv'.format(
start_date.strftime(DATETIME_FORMAT),
end_date.strftime(DATETIME_FORMAT),
))
注意 - 在代码中使用适当的分隔符和quotechar。 这只是开始 - 你可以使用它作为一个开始 - 每日聚合 - 应该可以使用此代码实现,但如果你想要一个小时每秒行csv - 你需要包装一点。
如果您有任何疑问 - 请做。