Как интерполировать значения для пустых строк по столбцам в пределах одного и того же имени строки, а затем скопировать интерполированные данные в исходный DataFrame? - PullRequest
1 голос
/ 14 апреля 2019

У меня есть электронная таблица со статистикой Мирового счастья за 2019 год, которая будет позже использована в задаче визуализации и линейной регрессии (это групповой проект, и моя часть заключается в очистке данных, чтобы иметь как можно меньше нулевых значений). насколько это возможно).

Меня интересуют только годы, в том числе и после 2010 года. Данные по некоторым странам полностью отсутствуют за определенный год (например, в Эфиопии отсутствуют данные за 2010 и 2011 годы). Я хотел бы предсказать недостающие параметры этих стран (такие как показатель жизни и логарифм ВВП на душу населения) путем интерполяции.

Файл можно найти здесь: https://s3.amazonaws.com/happiness-report/2019/Chapter2OnlineData.xls

То, что я делал до сих пор, - это создание нового DataFrame для каждой страны и попытка интерполяции для этой страны. (Код ниже.) Обратите внимание, что dropdata - это DataFrame, который я создал, удаляя страны, для которых слишком мало информации, например, Оман.

Кроме того, я вручную вставил строки в исходную электронную таблицу со страной и годом (например, Эфиопия, 2011) и пустыми значениями данных.

Но интерполяция не работает вообще. Я продолжаю видеть значения NaN, и при печати DataFrame новые вставленные строки не отображаются вообще.

Ниже приведен пример вывода.

Country name  Year  Life Ladder  Log GDP per capita  Social support  \
     Ethiopia  2012     4.561169            7.115237        0.658794   
     Ethiopia  2013     4.444827            7.189737        0.602482   
     Ethiopia  2014     4.506647            7.261595        0.640452   
     Ethiopia  2015     4.573155            7.335052        0.625597   
     Ethiopia  2016     4.297849            7.382929        0.718719   
     Ethiopia  2017     4.180315            7.455834        0.733540   
     Ethiopia  2018     4.379262            7.524517        0.740155   

     Healthy life expectancy at birth  Freedom to make life choices  \
                         55.200001                      0.776308   
                         55.799999                      0.706796   
                         56.400002                      0.693559   
                         57.000000                      0.802643   
                         57.500000                      0.744308   
                         58.000000                      0.717101   
                         58.500000                      0.740343   

     Generosity  Perceptions of corruption  
   -0.036612                        NaN  
   -0.000997                   0.750478  
    0.086612                   0.701800  
    0.118702                   0.567027  
    0.045363                   0.702881  
    0.007519                   0.756899  
    0.043274                   0.799466  

И код, который я использовал.

country_list = dropdata['Country name']
for country in country_list:
    countryDF = dropdata.loc[dropdata['Country name'] == country, :] #Creates a dataFrame for each country.
    countryDF2 = countryDF.iloc[0:20, 0:9]  #We are interested only in the first 9 rows.
    countryDF2.interpolate(method ='values', axis = 0, limit_direction ='both', limit = 3)

Все еще есть значения NaN, несмотря на то, что выполнили интерполяцию в обоих направлениях. Более того, я должен скопировать интерполированные значения из DataFrame каждой страны обратно в исходный DataFrame (который должен быть взят как dropdata) для всех строк. С чего начать?

1 Ответ

1 голос
/ 14 апреля 2019

Используйте пользовательскую функцию с GroupBy.apply только для отфильтрованных значений по позициям, но сначала добавьте отсутствующие строки на DataFrame.reindex с MultiIndex.from_product:

df = pd.read_excel('Chapter2OnlineData.xls')

mux = pd.MultiIndex.from_product([df['Country name'].unique(), 
                                  np.arange(df['Year'].min(), df['Year'].max() + 1)],
                                  names=['Country name','Year'])
df = df.set_index(['Country name','Year']).reindex(mux).reset_index()

print (df[df['Country name'] == 'Algeria'].iloc[0:20, 0:9])
  Country name  Year  Life Ladder  Log GDP per capita  Social support  \
28      Algeria  2005          NaN                 NaN             NaN   
29      Algeria  2006          NaN                 NaN             NaN   
30      Algeria  2007          NaN                 NaN             NaN   
31      Algeria  2008          NaN                 NaN             NaN   
32      Algeria  2009          NaN                 NaN             NaN   
33      Algeria  2010     5.463567            9.462701             NaN   
34      Algeria  2011     5.317194            9.471962        0.810234   
35      Algeria  2012     5.604596            9.485086        0.839397   
36      Algeria  2013          NaN                 NaN             NaN   
37      Algeria  2014     6.354898            9.509210        0.818189   
38      Algeria  2015          NaN                 NaN             NaN   
39      Algeria  2016     5.340854            9.541166        0.748588   
40      Algeria  2017     5.248912            9.540639        0.806754   
41      Algeria  2018     5.043086            9.557952        0.798651   

    Healthy life expectancy at birth  Freedom to make life choices  \
28                               NaN                           NaN   
29                               NaN                           NaN   
30                               NaN                           NaN   
31                               NaN                           NaN   
32                               NaN                           NaN   
33                         64.500000                      0.592696   
34                         64.660004                      0.529561   
35                         64.820000                      0.586663   
36                               NaN                           NaN   
37                         65.139999                           NaN   
38                               NaN                           NaN   
39                         65.500000                           NaN   
40                         65.699997                      0.436670   
41                         65.900002                      0.583381   

    Generosity  Perceptions of corruption  
28         NaN                        NaN  
29         NaN                        NaN  
30         NaN                        NaN  
31         NaN                        NaN  
32         NaN                        NaN  
33   -0.229078                   0.618038  
34   -0.204406                   0.637982  
35   -0.195859                   0.690116  
36         NaN                        NaN  
37         NaN                        NaN  
38         NaN                        NaN  
39         NaN                        NaN  
40   -0.191522                   0.699774  
41   -0.172413                   0.758704  

def f(x):
    x.iloc[0:20, 0:9] = x.iloc[0:20, 0:9].interpolate(method ='values',
                                                      axis = 0, 
                                                      limit_direction ='both', 
                                                      limit = 3)
    return x

df = df.groupby('Country name').apply(f)
print (df[df['Country name'] == 'Algeria'].iloc[0:20, 0:9])

   Country name  Year  Life Ladder  Log GDP per capita  Social support  \
28      Algeria  2005          NaN                 NaN             NaN   
29      Algeria  2006          NaN                 NaN             NaN   
30      Algeria  2007     5.463567            9.462701             NaN   
31      Algeria  2008     5.463567            9.462701        0.810234   
32      Algeria  2009     5.463567            9.462701        0.810234   
33      Algeria  2010     5.463567            9.462701        0.810234   
34      Algeria  2011     5.317194            9.471962        0.810234   
35      Algeria  2012     5.604596            9.485086        0.839397   
36      Algeria  2013     5.979747            9.497148        0.828793   
37      Algeria  2014     6.354898            9.509210        0.818189   
38      Algeria  2015     5.847876            9.525188        0.783389   
39      Algeria  2016     5.340854            9.541166        0.748588   
40      Algeria  2017     5.248912            9.540639        0.806754   
41      Algeria  2018     5.043086            9.557952        0.798651   

    Healthy life expectancy at birth  Freedom to make life choices  \
28                               NaN                           NaN   
29                               NaN                           NaN   
30                         64.500000                      0.592696   
31                         64.500000                      0.592696   
32                         64.500000                      0.592696   
33                         64.500000                      0.592696   
34                         64.660004                      0.529561   
35                         64.820000                      0.586663   
36                         64.980000                      0.556665   
37                         65.139999                      0.526666   
38                         65.320000                      0.496668   
39                         65.500000                      0.466669   
40                         65.699997                      0.436670   
41                         65.900002                      0.583381   

    Generosity  Perceptions of corruption  
28         NaN                        NaN  
29         NaN                        NaN  
30   -0.229078                   0.618038  
31   -0.229078                   0.618038  
32   -0.229078                   0.618038  
33   -0.229078                   0.618038  
34   -0.204406                   0.637982  
35   -0.195859                   0.690116  
36   -0.194991                   0.692048  
37   -0.194124                   0.693979  
38   -0.193257                   0.695911  
39   -0.192389                   0.697843  
40   -0.191522                   0.699774  
41   -0.172413                   0.758704  
...