#python #pandas #missing-data
#python #панды #отсутствует-данные
Вопрос:
Я дал следующий df
df = pd.DataFrame(data = {'day': [1, 1, 1, 2, 2, 3], 'pos': 2*[1, 14, 18], 'value': 2*[1, 2, 3]}
df
day pos value
0 1 1 1
1 1 14 2
2 1 18 3
3 2 1 1
4 2 14 2
5 3 18 3
и я хочу заполнить строки так, чтобы каждый день имел все возможные значения столбца ‘pos’
желаемый результат:
day pos value
0 1 1 1.0
1 1 14 2.0
2 1 18 3.0
3 2 1 1.0
4 2 14 2.0
5 2 18 NaN
6 3 1 NaN
7 3 14 NaN
8 3 18 3.0
Предложение:
df.set_index('pos').reindex(pd.Index(3*[1,14,18])).reset_index()
дает:
ValueError: cannot reindex from a duplicate axis
Ответ №1:
Давайте попробуем pivot
тогда stack
:
df.pivot('day','pos','value').stack(dropna=False).reset_index(name='value')
Вывод:
day pos value
0 1 1 1.0
1 1 14 2.0
2 1 18 3.0
3 2 1 1.0
4 2 14 2.0
5 2 18 NaN
6 3 1 NaN
7 3 14 NaN
8 3 18 3.0
Вариант 2: объединить с MultiIndex:
df.merge(pd.DataFrame(index=pd.MultiIndex.from_product([df['day'].unique(), df['pos'].unique()])),
left_on=['day','pos'], right_index=True, how='outer')
Вывод:
day pos value
0 1 1 1.0
1 1 14 2.0
2 1 18 3.0
3 2 1 1.0
4 2 14 2.0
5 3 18 3.0
5 2 18 NaN
5 3 1 NaN
5 3 14 NaN
Комментарии:
1. Спасибо. Работает. Я хотел добавить, что первый вариант кажется ограниченным одним столбцом: например, если столбцы [‘day’, ‘hour’, ‘pos’, ‘value’], и каждый день должен иметь все возможные значения ‘hour’, а каждый ‘hour’ должен иметь все возможные значения ‘hour’.значение ‘pos’. Не удалось заставить вариант 1 работать, вариант 2 работает нормально!
Ответ №2:
Вы можете reindex
:
s = pd.MultiIndex.from_product([df["day"].unique(),df["pos"].unique()], names=["day","pos"])
print (df.set_index(["day","pos"]).reindex(s).reset_index())
day pos value
0 1 1 1.0
1 1 14 2.0
2 1 18 3.0
3 2 1 1.0
4 2 14 2.0
5 2 18 NaN
6 3 1 NaN
7 3 14 NaN
8 3 18 3.0
Ответ №3:
Я бы избегал руководства product
по всем возможным значениям.
Вместо этого можно получить уникальные значения и только reindex
за день:
u = df.pos.unique()
df.groupby('day').apply(lambda s: s.set_index('pos').reindex(u))['value']
.reset_index()
day pos value
0 1 1 1.0
1 1 14 2.0
2 1 18 3.0
3 2 1 1.0
4 2 14 2.0
5 2 18 NaN
6 3 1 NaN
7 3 14 NaN
8 3 18 3.0