2016-11-22 1 views
0

У меня есть много файлов данных (файлы csv), расположенных в разных папках моих документов на моем компьютере. Все файлы csv имеют одинаковое количество столбцов, где имя каждого столбца одинаковое и в том же порядке, однако между файлами существует различное количество строк данных. Все файлы имеют «Datetime» в качестве своего первого столбца, где «YYYYMMDD HH: MM: SS» записывается по строкам данных.Для перебора нескольких папок для повторной выборки времени в нескольких файлах CSV и экспорта с автоматически созданным именем файла

Я хочу переделать все данные, чтобы создавать почасовые, ежедневные и ежемесячные данные из исходных файлов. Некоторые столбцы в файлах csv требуют суммирования данных за час, день и месяц, тогда как в других столбцах требуется усреднение данных по этим временным рамкам (согласованным во всех файлах csv). Я хочу, чтобы каждый оригинальный CSV-файл имел почасовую, ежедневную и месячную версию.

Все CSV файлы существуют в следующем inputpath, но на самом деле находится в других файлах в этом inputpath:

inputpath = 'C:/Users/cp_vm/Документы/данные/Input/Clean /'

Например, в папке «Очистить» есть еще две папки, и внутри этих папок есть другие, которые содержат все файлы csv. Я хочу читать во всех файлах csv, которые существуют за папкой «Чистота», без необходимости писать несколько «входных путей» и перевыполнять файлы, как упоминалось ранее.

Затем я хочу экспортировать эти передискретизированные фреймы данных в папки, из которых они пришли, и добавить к их именам «час», «день» или «месяц».

Ниже приведен пример фрагмента файлов csv.

enter image description here

Например, я хочу, чтобы дискретизацию данные минутный интервал в 15 ежечасно, суточные и месячные данные. Первые два столбца должны быть суммированы при повторной выборке, тогда как третий столбец должен быть усреднен по времени повторной выборки. Я понимаю, что df.resample ('h'). Sum() будет суммировать данные за час, а * .mean() будет усреднять данные за час, но сложно, когда разные столбцы требуют различной повторной выборки, а затем хотят объедините все эти столбцы вместе, а затем экспортируйте почасовой, ежедневный или ежемесячный файл в соответствующее место, где имя файла автоматически было изменено, чтобы показать, что оно выполняется ежечасно, ежедневно или ежемесячно.

Я понимаю, что это довольно описательно, но это вызывает у меня всевозможные задержки и перемещение файлов csv повлияет на другой скрипт python, который я уже написал. Любые предложения будут ценны. Заранее благодарю вас за любую помощь, которую вы можете предоставить.

ответ

0

Это трудно выяснить, где ваша проблема на самом деле :)

Но питон имеет что-то вроде 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 в секунду в течение часа - вам нужно немного его обернуть ,

Если у вас есть какие-либо вопросы - пожалуйста.

+0

Спасибо @ SebastianOpalczyński - Когда я печатаю (csv_files), я получаю список своих 88 CSV-файлов, что здорово. Но я хочу, чтобы иметь возможность перепрограммировать все 88 файлов для каждого из них почасовым, ежедневным и ежемесячным версиям, поскольку каждый из них имеет «Datetime» в качестве своего первого столбца. Некоторые столбцы необходимо суммировать, в то время как другие должны быть усреднены по временным рамкам повторной выборки. – user3299288

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