Использование только что назначенного столбца в операторе «groupby»? (метод сцепления с Пандами)

#python #pandas

Вопрос:

Я пользователь R ( dplyr ), который учится очищать данные с помощью pandas . Я практикуюсь в использовании набора данных ветряных турбин и хотел бы иметь возможность возвращать фрейм данных с указанием количества производителей в год в Британской Колумбии с 2000 года.

Фрагмент ниже возвращает ошибку NameError: name 'year' is not defined . Есть ли способ передать вновь сгенерированный столбец, year в данном случае, в groupby оператор внутри одной цепочки?

 import pandas as pd

wind_raw = pd.read_csv(
    "https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-10-27/wind-turbine.csv"
)

(
    wind_raw
    .loc[:,['province_territory', 'manufacturer', 'commissioning_date']]
    .assign(year = wind_raw.commissioning_date.str.replace(r'(d{4})(/d{4})*', r'1'))
    .assign(year = lambda row: pd.to_datetime(row.year))
    .query('province_territory == "British Columbia" and year >= 2000')
    .groupby(wind_raw.manufacturer, year)
    .size()
)

 

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

1. @ScottBoston спасибо! не могли бы вы подробнее рассказать о том, как я мог бы использовать pipe в этом случае?

2. пожалуйста, будьте осторожны со своими тегами, я вижу, что вы используете панд, а не r

Ответ №1:

Вы почти поняли, вам нужно только изменить groupby параметры:

 (
wind_raw
.loc[:,['province_territory', 'manufacturer', 'commissioning_date']]
.assign(year = wind_raw.commissioning_date.str.replace(r'(d{4})(/d{4})*', r'1'))
.assign(year = lambda row: pd.to_datetime(row.year))
.query('province_territory == "British Columbia" and year >= 2000')
.groupby(["manufacturer", "year"])
.size()
)
 

Выход

 manufacturer  year      
Enercon       2009-01-01    34
              2019-01-01     4
GE            2017-01-01    61
Leitwind      2010-01-01     1
Senvion       2017-01-01    10
Vestas        2011-01-01    48
              2012-01-01    79
              2014-01-01    55
 

Кроме того, есть пара вещей, которые можно упростить:

 (
wind_raw[['province_territory', 'manufacturer']]
.assign(year = wind_raw.commissioning_date.str.extract("(d{4})").astype(int))
.query('province_territory == "British Columbia" and year >= 2000')
.groupby(["manufacturer", "year"])
.size()
)
 

Ответ №2:

Чтобы напрямую ответить на ваш вопрос, вы можете указать свой выбор столбца в groupby методе в виде строк: .groupby(["manufacturer", "year"]) (мы используем список для группировки по нескольким столбцам).

И если вам интересно, вот еще один лакомый кусочек:

 .assign(year = lambda row: pd.to_datetime(row.year))
 

Передача функции assign методу не приводит к передаче каждой строки функции. Он фактически передает фрейм данных в его текущем виде.


Более того, вы можете использовать некоторые забавные цепочки методов даже внутри assign метода

 .assign(
    year = (wind_raw.commissioning_date
        .str.replace(r'(d{4})(/d{4})*', r'1'))
        # use the pipe method to pass the regex extracted column to `pd.to_datetime`
        .pipe(pd.to_datetime)) 
)

 

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

1. это потрясающе, большое вам спасибо за ваши идеи!