Как векторизовать операцию pandas

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

У меня есть набор данных о продажах домов с временными периодами (за квартал). Я хочу скорректировать цену в соответствии с изменением индекса цен на жилье в зависимости от региона. У меня есть отдельный фрейм данных с 3 столбцами, кварталом, регионом и%-ным изменением цены. В настоящее время я добиваюсь этого, выполняя итерации по обоим фреймам данных. Есть ли лучший способ?

Минимальный пример;

 import pandas as pd
houses_df = pd.DataFrame({'HousePrice' : [100000, 250000, 125000, 320000],
                          'Period' : ['2020Q1', '2020Q2', '2020Q1', '2020Q3'],
                          'Region' : ['NY-West', 'NY-East', 'NY-West', 'NY-East']})

HPindex_df = pd.DataFrame({'Periods' : ['2020Q1', '2020Q2', '2020Q3'] * 2,
                           'Regions' : ['NY-West', 'NY-West', 'NY-West', 'NY-East', 'NY-East', 'NY-East'],
                          'PriceIndex' : [1.1, 1.13, 0.87, 1.35, 1.21, 1.11]})
for index, row in houses_df.iterrows():
    for row1 in HPindex_df.itertuples():
        a = row1
        if row['Region'] == row1.Regions and row['Period'] == row1.Periods:
            houses_df.loc[index, 'HousePrice'] = houses_df.loc[index, 'HousePrice'] * row1.PriceIndex

print(houses_df)
   HousePrice  Period   Region
0    110000.0  2020Q1  NY-West
1    302500.0  2020Q2  NY-East
2    137500.0  2020Q1  NY-West
3    355200.0  2020Q3  NY-East

print(HPindex_df)
  Periods  Regions  PriceIndex
0  2020Q1  NY-West        1.10
1  2020Q2  NY-West        1.13
2  2020Q3  NY-West        0.87
3  2020Q1  NY-East        1.35
4  2020Q2  NY-East        1.21
5  2020Q3  NY-East        1.11
 

Я не думаю, что это лучший способ сделать это, поскольку это наивная реализация. Есть ли (векторизованные / встроенные функции pandas) -способ добиться этого?

Ответ №1:

Используйте DataFrame.merge с left_on и right_on , затем получите все 4 столбца в выходных данных:

 df = houses_df.merge(HPindex_df, 
                     left_on=['Period','Region'], 
                     right_on=['Periods','Regions'], 
                     how='left')
df['HousePrice'] = df['HousePrice'] * df['PriceIndex']
print (df)

   HousePrice  Period   Region Periods  Regions  PriceIndex
0    110000.0  2020Q1  NY-West  2020Q1  NY-West        1.10
1    302500.0  2020Q2  NY-East  2020Q2  NY-East        1.21
2    137500.0  2020Q1  NY-West  2020Q1  NY-West        1.10
3    355200.0  2020Q3  NY-East  2020Q3  NY-East        1.11
 

Для избежания этого можно использовать rename :

 d = {'Periods':'Period','Regions':'Region'}
df = houses_df.merge(HPindex_df.rename(columns=d), on=['Period','Region'], how='left')
df['HousePrice'] = df['HousePrice'] * df['PriceIndex']
print (df)

   HousePrice  Period   Region  PriceIndex
0    110000.0  2020Q1  NY-West        1.10
1    302500.0  2020Q2  NY-East        1.21
2    137500.0  2020Q1  NY-West        1.10
3    355200.0  2020Q3  NY-East        1.11
 

Или DataFrame.join с помощью DataFrame.set_index :

 df = houses_df.join(HPindex_df.set_index(['Periods','Regions']), on=['Period','Region'])
df['HousePrice'] = df['HousePrice'] * df['PriceIndex']
print (df)
   HousePrice  Period   Region  PriceIndex
0    110000.0  2020Q1  NY-West        1.10
1    302500.0  2020Q2  NY-East        1.21
2    137500.0  2020Q1  NY-West        1.10
3    355200.0  2020Q3  NY-East        1.11
 

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

1. черт возьми, Израэль, дай остальным из нас шанс ответить на эти вопросы pandas XD

2. @greg_data — Я думаю, что есть много вопросов без ответа 😉

3. Это было … быстро!