Фильтрация и добавление строки значения NaN - PullRequest
1 голос
/ 16 марта 2019

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

Country     Year    Value
USA         1991     22
USA         1992     3
USA         1993     10
China       1991     1
China       1993     15
Argentina   1991     6
Argentina   1992     4

Мне нужна функция, которая могла бы найти пропущенный год для каждой страны и добавить строку со значением NaN к фрейму данных.

Country     Year    Value
USA         1991     22
USA         1992     3
USA         1993     10
China       1991     1
China       1992     NaN
China       1993     15
Argentina   1991     6
Argentina   1992     4
Argentina   1993     NaN

Мне также нужно создать фрейм данных со значениями, основанными только на годах, когда у меня есть значения для всех стран.

Country     Year    Value
USA         1991     22
China       1991     1
Argentina   1991     6

1 Ответ

2 голосов
/ 16 марта 2019

Использование DataFrame.set_index с MultiIndex.from_product для DataFrame.reindex:

df = df.set_index(['Country','Year'])
mux = pd.MultiIndex.from_product(df.index.levels, names=df.index.names)
df = df.reindex(mux).reset_index()
print (df)
     Country  Year  Value
0  Argentina  1991    6.0
1  Argentina  1992    4.0
2  Argentina  1993    NaN
3      China  1991    1.0
4      China  1992    NaN
5      China  1993   15.0
6        USA  1991   22.0
7        USA  1992    3.0
8        USA  1993   10.0

И для групп без пропущенных значений:

vals = df1.loc[df1['Value'].isna(), 'Country'].unique()
df2 = df1[~df1['Country'].isin(vals)]
print (df2)
  Country  Year  Value
6     USA  1991   22.0
7     USA  1992    3.0
8     USA  1993   10.0

Альтернативой является использование DataFrame.unstack с DataFrame.stack:

s = df.set_index(['Country','Year']).unstack()
df1 = s.stack(dropna=False).reset_index()
print (df1)
     Country  Year  Value
0  Argentina  1991    6.0
1  Argentina  1992    4.0
2  Argentina  1993    NaN
3      China  1991    1.0
4      China  1992    NaN
5      China  1993   15.0
6        USA  1991   22.0
7        USA  1992    3.0
8        USA  1993   10.0

Для всех значений в столбцах используйте DataFrame.dropna:

df2 = s.dropna(axis=1).stack().reset_index()
print (df2)
     Country  Year  Value
0  Argentina  1991    6.0
1      China  1991    1.0
2        USA  1991   22.0

EDIT:

Если получите:

ValueError: невозможно обработать неуникальный мультииндекс!

это означает, что нет уникальных комбинаций столбцов Country и Year:

print (df)
     Country  Year  Value
0        USA  1991     22 <-duplicate USA, 1991
1        USA  1991      3 <-duplicate USA, 1991
2        USA  1993     10
3      China  1991      1
4      China  1993     15
5  Argentina  1991      6
6  Argentina  1992      4

решением является изменение set_index на groupby с некоторой агрегатной функцией, такой как mean, sum для уникальных комбинаций:

df = df.groupby(['Country','Year']).mean()
mux = pd.MultiIndex.from_product(df.index.levels, names=df.index.names)
df = df.reindex(mux).reset_index()
print (df)
     Country  Year  Value
0  Argentina  1991    6.0
1  Argentina  1992    4.0
2  Argentina  1993    NaN
3      China  1991    1.0
4      China  1992    NaN
5      China  1993   15.0
6        USA  1991   12.5
7        USA  1992    NaN
8        USA  1993   10.0
...