#python #pandas #data-analysis
#питон #панды #анализ данных
Вопрос:
У меня есть такой фрейм данных, как этот:
import pandas as pd
dates = ['2010-01-01', '2010-01-02','2010-01-01','2010-01-01', '2010-01-01','2010-01-01',
'2010-01-02', '2010-01-02','2010-01-02','2010-01-03', '2010-01-04','2010-01-04',
'2010-01-04', '2010-01-01','2010-01-05','2010-01-05', '2010-01-05','2010-01-01']
amounts = [14, 22, 10, 65, 23, 43, 12, 49, 10, 10, 20, 12, 12, 108, 61, 98, 17, 43 ]
types = ['Type1', 'Type1', 'Type1', 'Type2', 'Type1', 'Type3',
'Type1', 'Type2', 'Type1', 'Type2', 'Type2', 'Type3',
'Type2', 'Type1', 'Type3', 'Type2', 'Type1', 'Type3']
my_data = {'Date': dates, 'Amount': amounts, 'Type': types}
df = pd.DataFrame(data=my_data)
И я хочу построить графики (3 графика по 1 для каждого уникального типа) для среднего количества за каждый день для каждого типа. Но после агрегирования у меня нет нулей в те дни, когда не было суммы, поэтому есть 5 дат, но из-за набора данных в некоторых типах нет данных каждого типа, поэтому графики не могут быть построены. Есть ли способ решить эту проблему? Большое спасибо!
import matplotlib.pyplot as plt
dates_unique = df["Date"].unique()
types_unique = df["Type"].unique()
for Type in types_unique:
values = df.loc[df['Type'] == Type].groupby(df.Date).Amount.mean()
plt.plot_date(dates_unique, values, label=Type)
Комментарии:
1.
sns.lineplot(data=df, hue='Type', x='Date',y='Amount')
?2. Не совсем. Мне нужно сначала вычислить среднее значение каждого типа для каждого дня, а затем нанести его на график. Но все равно спасибо за подсказку!
3. Да, это именно то, что
sns.lineplot
нужно.4. Другой способ — сводная таблица:
df.pivot_table(index='Date', columns='Type', values='Amount').plot()
.
Ответ №1:
Для того, чтобы 0
(не NaN
) заменить отсутствующие данные, вы должны указать это явно. Кроме того, я бы рекомендовал выполнить повторную выборку с частотой, с которой вы собираетесь отображать свои данные, чтобы даты, которые полностью отсутствуют, не «замалчивались», а отображались с 0 count).
Так, например:
Альтернатива 1:
z = df.groupby([
pd.Grouper(key='Date', freq='D'), 'Type',
])['Amount'].mean().unstack().fillna(0)
Альтернатива 2:
z = df.pivot_table(
index='Date', columns='Type', values='Amount',
fill_value=0).resample('D').sum()
В любом случае, z
теперь:
Type Type1 Type2 Type3
Date
2010-01-01 38.750000 65 43
2010-01-02 14.666667 49 0
2010-01-03 0.000000 10 0
2010-01-04 0.000000 16 12
2010-01-05 17.000000 98 61
и вы можете легко ее отобразить:
z.plot(style='-o')