pandas
#pandas
Вопрос:
у меня есть фрейм данных ниже, я хочу убедиться, что если значение ELSE не существует в столбце, я должен его добавить.
мой источник фрейма данных приведен ниже
date zone RATE
2021-09-01 NY 90
2021-09-01 LA 80
2021-09-01 ELSE 10
2021-09-02 NY 60
2021-09-02 LA 70
ожидаемый результат
2021-09-01 NY 90
2021-09-01 LA 80
2021-09-01 ELSE 10
2021-09-02 NY 60
2021-09-02 LA 70
2021-09-02 ELSE 0
Ответ №1:
Использовать DataFrame.unstack
с DataFrame.stack
, для исходного порядка используется упорядоченный Categorical
:
df['zone'] = pd.Categorical(df['zone'], ordered=True, categories=df['zone'].unique())
df = df.set_index(['date','zone']).unstack(fill_value=0).stack().reset_index()
print (df)
date zone RATE
0 2021-09-01 NY 90
1 2021-09-01 LA 80
2 2021-09-01 ELSE 10
3 2021-09-02 NY 60
4 2021-09-02 LA 70
5 2021-09-02 ELSE 0
Альтернатива:
df['zone'] = pd.Categorical(df['zone'], ordered=True, categories=df['zone'].unique())
df = df.set_index(['date','zone'])
df = df.reindex(pd.MultiIndex.from_product(df.index.levels), fill_value=0).reset_index()
print (df)
date zone RATE
0 2021-09-01 NY 90
1 2021-09-01 LA 80
2 2021-09-01 ELSE 10
3 2021-09-02 NY 60
4 2021-09-02 LA 70
5 2021-09-02 ELSE 0
Или:
from itertools import product
df1 = pd.DataFrame(product(df['date'].unique(), df['zone'].unique()),
columns=['date','zone'])
df = df1.merge(df, how='left').fillna({'RATE':0}).astype({'RATE':int})
print (df)
date zone RATE
0 2021-09-01 NY 90
1 2021-09-01 LA 80
2 2021-09-01 ELSE 10
3 2021-09-02 NY 60
4 2021-09-02 LA 70
5 2021-09-02 ELSE 0
Комментарии:
1. У меня есть только один вопрос со стороны ~ pivot и unstack, похоже, сортируют столбцы самостоятельно, верно ~
2. спасибо @jezrael я хочу соблюдать тот же порядок, Нью-Йорк, Лос-Анджелес, тогда ЕЩЕ? пожалуйста?
Ответ №2:
Выполните pivot
тогда fillna
и stack
обратно
out = df.pivot(*df.columns).fillna(0).stack().reset_index(name='RATE')
Out[437]:
date zone RATE
0 2021-09-01 ELSE 10.0
1 2021-09-01 LA 80.0
2 2021-09-01 NY 90.0
3 2021-09-02 ELSE 0.0
4 2021-09-02 LA 70.0
5 2021-09-02 NY 60.0