Использование переиндексации внутри функции дает только значения NaN - PullRequest
0 голосов
/ 22 октября 2019

Простой пример фрейма данных

df = pd.DataFrame({
    'year': [1900, 1901, 1901, 1901, 1902, 1903, 1903, 1903, 1905]
})

У меня есть функция ниже, которая принимает фрейм данных pandas:

def my_function(df):
    df = df.groupby(['year']) # group the df by year
    new_df = pd.DataFrame() # make a new empty df
    new_df['frequency'] = df['year'].count() # get frequency counts for each year
    return new_df

Однако, вывод для этого не дает мне 0 подсчет частоты за пропущенные годы.

Идеальный вывод my_function (df):

year frequency
1900 1
1901 3
1902 1
1903 3
1904 0
1905 1
Current output of my_function(df):
1900 1
1901 3
1902 1
1903 3
1905 1

Я думаю, что я близок с pd.reindex (), но мне нужно направление.

Я отсканировал документы для pd.reindex () и попытался просмотреть этот постполучающий пост , а также этот иЯ до сих пор не смог ее решить.

Я определил диапазон идеальных лет в новой переменной

new_idx = range(1900, 1905)

И затем попытался реализовать pd.reindex() примерно так: new_df.reindex(new_idx, fill_value=0)

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

def my_function(df):
    new_idx = range(1900, 1905)
    df = df.groupby(['year'])
    new_df = pd.DataFrame()
    new_df['frequency'] = df['year'].count()
    new_df = new_df.reindex(new_idx, fill_value=0)
    return new_df

Однако это приводит к новому pd.dataframe (), которыйжелаемый размер (длина года в new_idx), но он переопределяет все значения частоты на 0, а не только на «добавленные» годы.

Идеальный выход слегка настроенный my_function(df):

year frequency
1900 1
1901 3
1902 1
1903 3
1904 0
1905 1

Текущий выход слегка настроенный my_function(df):

year frequency
1900 0
1901 0
1902 0
1903 0
1904 0
1905 0

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Вы хотите Series.value_counts + Series.reindex

new_df=( df['year'].value_counts()
                   .reindex(range(df['year'].min(),df['year'].max()+1),fill_value=0)
                   .rename_axis('year')
                   .reset_index(name='frecuency')
                    )
print(new_df)

       year  frecuency
0  1900          1
1  1901          3
2  1902          1
3  1903          3
4  1904          0
5  1905          1
0 голосов
/ 22 октября 2019

Вы можете использовать pd.date_range + pd.Series.value_counts :

import pandas as pd

df = pd.DataFrame({
    'year': [1900, 1901, 1901, 1901, 1902, 1903, 1903, 1903, 1905]
})

# generate date range between minimum and maximum year, with yearly frequency
range = pd.date_range(start=pd.datetime(df.min(), 1, 1), end=pd.datetime(df.max(), 1, 1), freq='AS')

# fill each year with the corresponding count set missing to zero
result = pd.Series(range.year, index=range.year).map(df.year.value_counts()).fillna(0)

print(result)

Выход

1900    1.0
1901    3.0
1902    1.0
1903    3.0
1904    0.0
1905    1.0
dtype: float64

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

...