Панды Объединить сгруппированный фрейм данных с другим фреймом для каждой группы - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть такой тип данных:

id  date        temperature

1   2011-09-12   12
    2011-09-15   12
    2011-10-13   12
2   2011-12-12   14
    2011-12-24   15

Я хочу убедиться, что для каждого идентификатора устройства есть записи температуры для каждого дня, если значение существует, оно будет скопировано сверху, если оно неустановит 0.

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

, используя pd.DataFrame(0, index=pd.range('2011-01-01', '2011-12-12'), columns=['temperature'])

date        temperature

2011-01-01     0
.
.
.
2011-12-12    0

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

Я застрял на шаге слияния, просто слияние в столбце даты не работает, т.е.

pd.merge(df1, df2, on=['date'])

дает пустой кадр данных.

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

В качестве альтернативы ответа Джезраэля вы также можете выполнить следующую итерацию, особенно если вы хотите сохранить идентификатор своего устройства в неизменном виде:

data={"date":[pd.Timestamp('2011-09-12'), pd.Timestamp('2011-09-15'), pd.Timestamp('2011-10-13'),pd.Timestamp('2011-12-12'),pd.Timestamp('2011-12-24')],"temperature":[12,12,12,14,15],"sensor_id":[1,1,1,2,2]}
df1=pd.DataFrame(data,index=data["sensor_id"])

df2=pd.DataFrame(0, index=pd.date_range('2011-01-01', '2011-12-12'), columns=['temperature','sensor_id'])

for i,row in df1.iterrows():
    df2.loc[df2.index==row["date"], ['temperature']] = row['temperature']
    df2.loc[df2.index==row["date"], ['sensor_id']] = row['sensor_id']

for t in data["date"]:
    print(df2[df2.index==t])

Обратите внимание, что df2 в вашем вопросе идет только к 2011-12-12, поэтому последний print() вернет пустой DataFrame. Я не был ли ты сделал это нарочно.

Кроме того, в зависимости от изменчивости и плотности ваших фактических данных может иметь смысл использовать:

for s in [1,2]: ## iterate over device ids
    ma=(df['sensor_id']==s)
    df.loc[ma]=df.loc[ma].fillna(method='ffill') # fill forward

следовательно, неполный временной ряд будет заполнен (вперед) последним измеренным значением температуры. Конечно, зависит от качества ваших данных, и df.resample() может иметь больше смысла.

0 голосов
/ 17 апреля 2019

Создать MultiIndex с помощью MultiIndex.from_product и объединить с помощью обоих MultiIndex es:

mux = pd.MultiIndex.from_product([df.index.levels[0], 
                                  pd.date_range('2011-01-01', '2011-12-12')],
                                  names=['id','date'])
df1 = pd.DataFrame(0, index=mux, columns=['temperature'])

df = pd.merge(df1, df, left_index=True, right_index=True, how='left')

Если хотите только один столбец temperature:

df = pd.merge(df1, df, left_index=True, right_index=True, how='left', suffixes=('','_'))
df['temperature'] = df.pop('temperature_').fillna(df['temperature'])

Другая идея заключается в использовании itertools.product для 2 columns DataFrame:

from  itertools import product
data = list(product(df.index.levels[0],  pd.date_range('2011-01-01', '2011-12-12')))

df1 = pd.DataFrame(data, columns=['id','date'])
df = pd.merge(df1, df, left_on=['id','date'], right_index=True, how='left')

Другая идея заключается в использовании DataFrame.reindex:

mux = pd.MultiIndex.from_product([df.index.levels[0], 
                                  pd.date_range('2011-01-01', '2011-12-12')],
                                  names=['id','date'])

df = df.reindex(mux, fill_value=0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...