Как отделить год от даты и сделать новый столбец; как быть с високосными годами

Я очень новичок в кодировании (это первый код, который я пишу).

У меня есть несколько CSV-файлов с одинаковыми заголовками. Файлы соответствуют почасовой концентрации озона на каждый день года, и каждый файл представляет собой отдельный год [диапазон с 2009 по 2020 год]. У меня есть столбец «дата», который содержит год-месяц-день, и у меня есть столбец для часа дня (0-23). Я хочу отделить год от дня месяца, объединить час с днем ​​месяца и сделать это индексом, а затем объединить другие файлы csv в один фрейм данных.

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

Кроме того, если у вас есть какие-либо советы о том, как упростить мой процесс, не стесняйтесь поделиться!

Заранее спасибо за помощь.

Обновление. Я воспользовался приведенным ниже советом Rookie, но после импорта данных в формате CSV я получаю сообщение об ошибке:

import pandas as pd
import os
path = "C:/Users/heath/Documents/ARB project Spring2020/ozone/SJV/SKNP"
df = pd.DataFrame()
for file in os.listdir(path):
    df_temp = pd.read_csv(os.path.join(path, file))
    df = pd.concat((df, df_temp), axis = 0)

Сначала я получаю сообщение об ошибке OSError: Initializing from file failed. Я попытался решить проблему, добавив engine = 'python' по совету OSError : Ошибка инициализации из файла в CSV в Pandas, но теперь я получаю PermissionError: [Errno 13] Permission denied: 'C:/Users/heath/Documents/ARB project Spring2020/ozone/SJV/SKNP\\.ipynb_checkpoints'

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


person Heather    schedule 04.06.2020    source источник
comment
Здравствуйте и добро пожаловать в StackOverflow. Не могли бы вы поделиться фрагментом кода, который вы начинаете тестировать?   -  person pyOliv    schedule 04.06.2020


Ответы (1)


Во-первых, вы хотите определить, с каким типом столбца вы имеете дело, когда он находится в кадре данных pandas. Это можно сделать с помощью метода dtypes. Например, если ваш DataFrame df, вы можете сделать df.dtypes, что позволит вам узнать, какие типы столбцов. Если вы видите тип object, это говорит вам, что pandas интерпретирует объект как строку (последовательность символов, а не фактическое значение даты или времени). Если вы видите datetime64[ns], pandas знает, что это значение даты и времени (объединенные дата и время). Если вы видите timedelta[ns], pandas знает, что это разница во времени (подробнее об этом позже).

Если dtype равны objects, давайте преобразуем их в тип datetime64[ns], чтобы мы могли сообщить пандам, что имеем дело со значениями даты/времени. Это можно сделать простым переназначением. Например, если формат даты — ГГГГ-мм-дд (2020-06-04), мы можем преобразовать столбец даты, используя следующий метод (при условии, что имя вашего столбца даты — «Дата»). Обратитесь к strftime для другого форматирования.

df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d")

Колонка времени немного сложнее. Pandas не знает только время, поэтому нам нужно преобразовать время в timedelta[64]. Если формат времени — чч:мм:сс (т. е. «21:02:24»), мы можем использовать следующий метод для преобразования типа object.

df["Time"] = pd.to_timedelta(df["Time"])

Если формат отличается, вам потребуется преобразовать формат строки в формат чч:мм:сс.

Теперь, чтобы объединить эти столбцы, мы можем просто добавить их:

df["DateTime"] = df["Date"] + df["Time"]

Чтобы создать упомянутый вами отформатированный столбец даты и времени, вы можете сделать это, создав новый столбец в строковом формате. Ниже будет указано «06-04 21», что означает 4 июня в 9 часов вечера. strftime может указать любой желаемый формат.

df["Formatted_DateTime"] = df["DateTime"].dt.strftime("%m-%d %H")

Вам нужно будет сделать это для каждого файла. Я рекомендую использовать здесь цикл for. Ниже приведен полный фрагмент кода. Это, очевидно, будет варьироваться в зависимости от ваших типов столбцов, имен файлов и т. д.

import os # module to iterate over the files
import pandas as pd

base_path = "path/to/directory" # This is the directory path where all your files are stored

# It will be faster to read in all files at once THEN format the date
df = pd.DataFrame()
for file in os.listdir(base_path):
    df_temp = pd.read_csv(os.path.join(base_path, file)) # This will read every file in the base_path directory
    df = pd.concat((df, df_temp), axis=0) # Concatenating (merging) the files

# Formatting the data
df["Date"] = pd.to_datetime(df["Date"], format="%Y-%m-%d") # Date conversion
df["Time"] = pd.to_timedelta(df["Time"]) # Time conversion
df["DateTime"] = df["Date"] + df["Time"] # Combine date and time to single column
df["Formatted_DateTime"] = df["DateTime"].dt.strftime("%m-%d %H") # Format the datetime values

Теперь, когда все отформатировано, средняя часть дается легко. Поскольку вас интересует только усреднение значений для каждого часа месяца и дня, мы можем использовать возможность группировки.

df_group = df.groupby(["Formatted_DateTime"]) # This will group you data by unique values of the "Formatted_DateTime" column
df_average = df_group.mean() # This will average your data within each group (accounting for the leap years)

Всегда приятно проверить свою работу!

print(df_average.head(5)) # This will print the first 5 days averaged values
person Rookie    schedule 05.06.2020
comment
Вау! Большое спасибо за подробный ответ! Знание этих мелких деталей очень полезно. - person Heather; 07.06.2020
comment
Если это полезно для вас, примите ответ как решение, нажав на галочку слева от ответа. Спасибо! - person Rookie; 08.06.2020