簡體   English   中英

Pandas將Grouped-by數據幀與每個組的另一個數據幀合並

[英]Pandas Merge a Grouped-by dataframe with another dataframe for each group

我有一個像這樣的數據框:

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

我想確保每個設備ID都有每天的溫度記錄,如果值存在,它將從上面復制,如果它沒有我將放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

現在,對於每個id,我想合並這個數據幀,這樣我就可以獲得每個id的全年條目。

我陷入了合並步驟,只是合並日期列不起作用,即

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

給出一個空白的數據幀。

通過MultiIndex.from_product創建MultiIndex並通過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.product2 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)

作為jezrael的答案的替代方案,您還可以執行以下迭代,尤其是如果您希望保持設備ID完整:

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()可能更有意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM