Python (Pandas) Как объединить 2 фрейма данных с разными датами в инкрементном порядке?

#python #pandas #dataframe #merge #concat

#python #pandas #фрейм данных #слияние #конкатенация

Вопрос:

Я пытаюсь объединить 2 фрейма данных по индексу даты по порядку. Возможно ли это?

Пример кода того, что мне нужно для манипулирования

Ссылка для sg_df:https://query1.finance .yahoo.com/v7/finance/download/^STI?P=^STI?period1=1442102400amp;period2=1599955200amp;interval=1moamp;events=history

Ссылка для facemask_compliance_df:https://today .yougov.com/topics/international/articles-reports/2020/05/18/international-covid-19-tracker-update-18-may (Отслеживание изменений поведения YouGov COVID-19: ношение маски для лица в общественных местах)

 # Singapore Index
# Read file
# Format Date
# index date column for easy referencing
sg_df = pd.read_csv("^STI.csv")
conv = lambda x: datetime.strptime(x, "%d/%m/%Y")
sg_df["Date"] = sg_df["Date"].apply(conv)
sg_df.sort_values("Date", inplace = True)
sg_df.set_index("Date", inplace = True)

# Will wear face mask in public
# Read file
# Format Date, Removing time
# index date column for easy referencing
facemask_compliance_df = pd.read_csv("yougov-chart.csv")
convert1 = lambda x: datetime.strptime(x, "%d/%m/%Y %H:%M") 
facemask_compliance_df["DateTime"] = facemask_compliance_df["DateTime"].apply(convert1).dt.date
facemask_compliance_df.sort_values("DateTime", inplace = True)
facemask_compliance_df.set_index("DateTime", inplace = True)

sg_df = sg_df.merge(facemask_compliance_df["Singapore"], left_index = True, right_index = True, how = "outer").sort_index()

  

и я хочу вывести таблицу, подобную этой.

введите описание изображения здесь

Пожалуйста, дайте мне знать, если вам понадобится дополнительная информация, я любезно предоставлю их вам в ближайшее время, если смогу.

Редактировать:

Это проблема

введите описание изображения здесь

данные из yougov-диаграммы

введите описание изображения здесь

Я думаю, что он считывает даты, даже если он не из Сингапура

Комментарии:

1. Итак, нужна сортировка? Или избежать сортировки? Есть datetimeindex? Потому что в образце данных нет.

2. Привет @jezrael, я сейчас предоставлю некоторые. Дайте мне минутку. Да, мне нужны даты для сортировки

3. Привет @jezrael, я попробовал ваш moethod, и это показывает перехват обоих фреймов данных

4. Я протестирую это прямо сейчас. Спасибо за ваше время @jezrael

5. Также изменены данные для чтения файлов. Если хотите использовать только ваше изменение facemask_compliance_df["DateTime"] = facemask_compliance_df["DateTime"].apply(convert1).dt.date на facemask_compliance_df["DateTime"] = facemask_compliance_df["DateTime"].apply(convert1).dt.floor('d')

Ответ №1:

Использовать:

  1. merge для объединения в таблицы.

1.1. on чтобы выбрать, в каком столбце объединить:

Имена столбцов или индексов для объединения. Они должны быть найдены в обоих фреймах данных. Если on значение None и не объединяется по индексам, то по умолчанию это означает пересечение столбцов в обоих фреймах данных.

1.2. outer опция:

внешний: используйте объединение ключей из обоих фреймов, аналогично полному внешнему соединению SQL; сортируйте ключи лексикографически.

  1. sort_values для сортировки по дате
 import pandas as pd

df1 = pd.read_csv("^STI.csv")

df1['Date'] = pd.to_datetime(df1.Date)

df2 = pd.read_csv("yougov-chart.csv")

df2['Date'] = pd.to_datetime(df2.DateTime)

result = df2.merge(df1, on='Date', how='outer')
result = result.sort_values('Date')

print(result)
  

Вывод:

         Date  US_GDP_Thousands  Mask Compliance
6 2016-02-01               NaN             37.0
7 2017-07-01               NaN             73.0
8 2019-10-01               NaN             85.0
0 2020-02-21              50.0             27.0
1 2020-03-18              55.0              NaN
2 2020-03-19              60.0              NaN
3 2020-03-25              65.0              NaN
4 2020-04-03              70.0              NaN
5 2020-05-14              75.0              NaN
  

Комментарии:

1. Спасибо за ваш вклад, я немедленно протестирую это!

2. Привет, @Aviv Yanic, Да! Это результат, который я ищу! Однако я не могу воспроизвести это с моими данными! Не могли бы вы любезно взглянуть на мой обновленный вопрос, пожалуйста?

3. Да 🙂 Пытался загрузить второй набор данных с [link], но не нашел его. Не могли бы вы предоставить другую ссылку на набор данных?

4. Я не могу! Вот и связь! Вам нужно прокрутить вниз до той части, где они отображаются (отслеживание изменений поведения YouGov COVID-19: ношение маски для лица в общественных местах), там есть кнопка с 3 линиями для загрузки файла CSV. Перед загрузкой вы можете отменить выбор всех стран и выбрать только Сингапур

5. Большое спасибо. Я действительно ценю это. @Aviv Yaniv

Ответ №2:

Сначала используйте параметры parse_dates и index_col в read_csv для DatetimeIndex в обоих, а во втором удаляйте время на Series.dt.floor :

 sg_df = pd.read_csv("^STI.csv", 
                    parse_dates=['Date'], 
                    index_col=['Date'])

facemask_compliance_df = pd.read_csv("yougov-chart.csv", 
                                     parse_dates=['DateTime'],
                                     index_col=['DateTime'])
facemask_compliance_df["DateTime"] = facemask_compliance_df["DateTime"].dt.floor('d')
  

Затем используйте DataFrame.merge по индексу с помощью внешнего соединения, а затем отсортируйте индекс по DataFrame.sort_index :

 df = sg_df.merge(facemask_compliance_df, 
                 left_index=True, 
                 right_index=True, 
                 how='outer').sort_index()
print (df)
            Mask Compliance  US_GDP_Thousands
Date                                         
2016-02-01             37.0               NaN
2017-07-01             73.0               NaN
2019-10-01             85.0               NaN
2020-02-21             27.0              50.0
2020-03-18              NaN              55.0
2020-03-19              NaN              60.0
2020-03-25              NaN              65.0
2020-04-03              NaN              70.0
2020-05-14              NaN              75.0
  

Комментарии:

1. привет @jezrael извините, что снова беспокою вас, но у меня есть 4 столбца в facemask_compliance_df. Для обозначения 4 разных стран. По какой-то причине при объединении программа также использует мой индекс других стран, что делает целую строку пустой, только с датой индексации. Позвольте мне показать вам мой обновленный код выше.

2. @HOA — Как вы думаете, проблема в данных из вопроса?

3. Я не думаю, что у данных есть какие-либо проблемы. Я только что опубликовал проблему

4. Так, например, 25/02/2020 находится в обоих фреймах данных и не совпадает?

5. Я обновил новую картинку! Он привел все даты, в том числе из других столбцов

Ответ №3:

Если я правильно помню, в numpy вы можете сделать v.stack или h.stack. зависит от того, как вы хотите объединить их вместе.

в pandas было что-то вроде объединенияhttps://pandas.pydata.org/docs/user_guide/merging.html который я использовал для объединения фреймов данных

Комментарии:

1. Спасибо за ваш любезный вклад! Я протестирую это прямо сейчас!