Сравнение фрейма данных дата-время с фреймом данных периода - PullRequest
0 голосов
/ 28 мая 2019

Я застрял с простой проблемой pandas dataframe и, возможно, кто-то сталкивался с такой ситуацией раньше ...

Заранее спасибо:)

Привет, у меня двафреймы данных, df1 и df2:

df1

unique_id    timestamp
1            2019-01-21
2            2019-02-01
3            2019-04-05
4            2019-05-01
5            2019-05-12
...          ...

df2

classification     from            to
A                  2019-01-05      2019-02-02
B                  2019-02-03      2019-02-28
C                  2019-03-01      2019-04-05
D                  2019-04-06      2019-05-03
E                  2019-05-04      2019-05-31
...                ...             ...

Моя цель - сравнить каждую метку времени в df1 с каждым с до интервал дат в df2 и возможность классифицировать каждый уникальный_ид df1 с соответствующей классификацией df2

Я пробовал что-то вроде этого:

df1.loc[(df1['timestamp'] > df2['from]) & (df1['timestamp'] < df2['to']), 'class'] = df2['classification']´

всегда получаю ValueError: Может сравнивать только объекты Series с одинаковыми метками , несмотря на то, что оба типа dtime-типов datetime одинаковы, datetime64 [нс] ...

Ожидаемый результат :

unique_id         timestamp        classification
1                 2019-01-21       A
2                 2019-02-01       A
3                 2019-04-05       C
4                 2019-05-01       D
5                 2019-05-12       E
...               ...              ...

Ответы [ 3 ]

0 голосов
/ 28 мая 2019

попробовать:
import numpy as np
сейчас вместо
df1['timestamp'] > df2['from]
попробовать:
np.greater(df1['timestamp'],df2['from])
похоже, вы пытаетесь получить истинный \ ложный ответ.
возможно, захотите взглянуть здесь: https://docs.scipy.org/doc/numpy/reference/routines.logic.html

0 голосов
/ 29 мая 2019

Вы смешиваете индекс обоих данных.С этим синтаксисом, который вы предлагаете, сравнение выполняется строка за строкой .Вы можете просто увидеть это, если мы увидим следующие фреймы данных (с другим размером):

df1 = pd.DataFrame(
    [[1, "2019-01-21"],
    [2, "2019-02-01"],
    [3, "2019-04-05"],
    [4, "2019-04-05"],
    [5, "2019-04-05"],
    [6, "2019-04-05"],
    [7, "2019-05-01"],
    [8, "2019-05-12"]],
    columns=["unique_id", "timestamp"])

df2 = pd.DataFrame([
    ["A", "2019-01-05", "2019-02-02"],
    ["D", "2019-04-06", "2019-05-03"],
    ["C", "2019-03-01", "2019-04-05"],
    ["B", "2019-02-03", "2019-02-28"],
    ["E", "2019-05-04", "2019-05-31"],],
    columns=["classification", "from", "to"])

# Comparaison of different dataframes
print((df1['timestamp'] > df2['from']))

Произошла ошибка:

ValueError: Может сравнивать только идентично помеченные объекты Series

Здесь , вы хотите сравнить согласно соответствующий интервал даты и времени .Таким образом, вы должны различать оба кадра данных.Чтобы преобразовать строковые данные в дату, pandas.to_datetime выполните работу (doc)

Вот один из способов сделать это:

# import modules
import pandas as pd

df1 = pd.DataFrame(
    [[1, "2019-01-21"],
    [2, "2019-02-01"],
    [3, "2019-04-05"],
    [4, "2019-04-05"],
    [5, "2019-04-05"],
    [6, "2019-04-05"],
    [7, "2019-05-01"],
    [8, "2019-05-12"]],
    columns=["unique_id", "timestamp"])

df2 = pd.DataFrame([
    ["A", "2019-01-05", "2019-02-02"],
    ["D", "2019-04-06", "2019-05-03"],
    ["C", "2019-03-01", "2019-04-05"],
    ["B", "2019-02-03", "2019-02-28"],
    ["E", "2019-05-04", "2019-05-31"],],
    columns=["classification", "from", "to"])

# convert to datetime
df1["timestamp"] = pd.to_datetime(df1["timestamp"], format="%Y-%m-%d")
df2[["from", "to"]] = df2[["from", "to"]].apply(pd.to_datetime, format="%Y-%m-%d")

# Try to compare 2 different dataframes
# print((df1['timestamp'] > df2['from']))

class_column = []
for index, row in df1.iterrows():
    class_fd2 = df2[(df2["from"] <= row["timestamp"]) & (df2["to"] >= row["timestamp"])]["classification"].values[0]
    class_column.append(class_fd2)
df1["class1"] = class_column
print(df1)
#    unique_id  timestamp class1
# 0          1 2019-01-21      A
# 1          2 2019-02-01      A
# 2          3 2019-04-05      C
# 3          4 2019-04-05      C
# 4          5 2019-04-05      C
# 5          6 2019-04-05      C
# 6          7 2019-05-01      D
# 7          8 2019-05-12      E

Вы также можете сделать это вфункция, применяемая к df1:

def set_class(row):
    return df2[(df2["from"] <= row["timestamp"]) & (
        df2["to"] >= row["timestamp"])]["classification"].values[0]
# Process
df1["class2"] = df1.apply(set_class, axis=1)
print(df1)
#    unique_id  timestamp class1 class2
# 0          1 2019-01-21      A      A
# 1          2 2019-02-01      A      A
# 2          3 2019-04-05      C      C
# 3          4 2019-04-05      C      C
# 4          5 2019-04-05      C      C
# 5          6 2019-04-05      C      C
# 6          7 2019-05-01      D      D
# 7          8 2019-05-12      E      E
0 голосов
/ 28 мая 2019

Что бы я лично сделал, это конвертировал метку времени в метку времени Unix.

for row in df1['timestamp']:
    row = int(mktime(row.timetuple())   

сделайте то же самое для df2, чтобы получить начальную и конечную метки времени, и тогда вы можете использовать df1.loc[(df1['timestamp'] > df2['from]) & (df1['timestamp'] < df2['to']), 'class'] = df2['classification']´, который вы написали, без получения сообщения об ошибке

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...