Как остановить поднабор Dataframe от «запоминания» старых значений

1

Извините за странную формулировку, но я не знал, как лучше ее описать. Я буду переводить свою проблему на условия США, чтобы облегчить понимание. Моя проблема заключается в том, что у меня есть национальная база данных с государствами и районами, и мне нужно работать только с районами из Флориды, поэтому я делаю это:

df_fl=df.loc[df.state=='florida'].copy()

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

df_final=df_fl.groupby(['district']).mean()

Но это приводит к тому, что с каждой областью в базе данных имеется блок данных. Все строки из районов, которые не во Флориде, заполнены нанами. Я предполагаю, что это простое решение, но я не смог его найти. Это похоже на то, что он работает так же, как и он.

Итак, вы можете помочь мне исправить это?

Заранее спасибо,

Изменение: мои данные выглядели так:

District   state      Salary
   1        Florida    1000
   1        Florida    2000
   2        Florida    2000
   2        Florida    3000
   3        California 3000

df_fl, то выглядит следующим образом:

District   state      Salary
   1        Florida    1000
   1        Florida    2000
   2        Florida    2000
   2        Florida    3000

И после применения

df_final=df_fl.groupby(['district']).mean()

Я ожидал получить следующее:

District   Salary
   1        1500
   2        2500

Но я получаю это:

District   Salary
   1        1500
   2        2500
   3         nan

Очевидно, очень упрощенная версия, но ядро остается.

  • 1
    Можете ли вы поделиться некоторыми данными, чтобы воспроизвести / отследить вывод? Я новичок во фреймах данных, но мне было интересно, не могли бы вы попробовать df_final =df.loc[df.state=='florida'].groupby(['district']).mean()
  • 2
    Невозможно воспроизвести, когда я воссоздаю кадр данных, как вы описываете ( pandas 0.21.1 )
Теги:
pandas
group-by

2 ответа

3
Лучший ответ

Поскольку piRSquared уже объяснил это, это происходит только с категориальными данными. Начиная с 0.23.0 groupby имеет новый "наблюдаемый" аргумент, который переключает это поведение. MCVE, взятый из piRSquared:

>>> df = pd.DataFrame(dict(
    State=list('CCCCFFFF'),
    District=list('WXWXYYZZ'),
    Value=range(1, 9)
))
>>> df.assign(
    District=pd.Categorical(df.District)
).query('State == "F"').groupby('District').Value.mean()
District
W    NaN
X    NaN
Y    5.5
Z    7.5
Name: Value, dtype: float64
>>> df.assign(
    District=pd.Categorical(df.District)
).query('State == "F"').groupby('District', observed=True).Value.mean()
District
Y    5.5
Z    7.5
Name: Value, dtype: float64
  • 1
    Очень хорошо. Я не знал об этом варианте (сейчас я знаю). @JuanC Я совсем не против, если это принятый ответ. Он использует API, как и предполагалось. Чтобы быть более точным, я предпочитаю это решение, чем мое.
  • 0
    Если это так, я отмечу это как ответ, но оба были очень поучительными. Спасибо обоим!
5

Это потому, что столбец 'District' является категоричным.

MCVE

df = pd.DataFrame(dict(
    State=list('CCCCFFFF'),
    District=list('WXWXYYZZ'),
    Value=range(1, 9)
))

Без категориальных

df.query('State == "F"').groupby('District').Value.mean()

District
Y    5.5
Z    7.5
Name: Value, dtype: float64

С категориальным

df.assign(
    District=pd.Categorical(df.District)
).query('State == "F"').groupby('District').Value.mean()

District
W    NaN
X    NaN
Y    5.5
Z    7.5
Name: Value, dtype: float64

Решение

Много способов сделать это. Одним из способов сохранения категориальной типизации является использование метода, remove_unused_categories

df = df.assign(District=df.District.cat.remove_unused_categories())
  • 1
    Этот хороший ответ должен быть принят
  • 1
    Точно ответ. Это было не так просто, как я ожидал, но приятно узнать о возможности удаления неиспользуемых категорий! большое спасибо

Ещё вопросы

Сообщество Overcoder
Наверх
Меню