id start end
1 2001 2005
2 2004 2007
output
id date
1 2001
1 2002
1 2003
1 2004
1 2005
2 2004
2 2005
2 2006
2 2007
my logics
df=pd.concat([pd.DataFrame({'start': pd.date_range(row.start, row.end, freq='AS'),
'id': row.id}, columns=['start', 'id'])
for i, row in df.iterrows()], ignore_index=True)
df1 = (pd.concat([pd.Series(r.id, pd.date_range(r.start, r.end, freq='AS')) for r in df.itertuples()]) .reset_index())
В моем фрейме данных минимум 300 000 строк, так что это неэффективные решения. Есть ли более эффективное решение?
примечание: начало и конец - годовой, ежемесячный, ежедневный .... форматы. Я привел годовой пример.
начало и конец - даты в формате гггг. вы сказали, что это нормально, но для других, таких как формат ггггмм, он не получит мои ответы
у меня разные форматы






Может быть, вен может использовать stack с groupbyrange
df.set_index('id').stack().groupby(level=0).apply(lambda x : pd.Series(list(range(x.iloc[0],x.iloc[1]+1)))).reset_index()
Out[746]:
id level_1 0
0 1 0 2001
1 1 1 2002
2 1 2 2003
3 1 3 2004
4 1 4 2005
5 2 0 2004
6 2 1 2005
7 2 2 2006
8 2 3 2007
он работает только для этого формата yyyy. У меня также есть форматы yyyymm и yymmdd Это решение не работает для меня
@raam df.set_index('id').apply(lambda x : x.str[:4])
можешь объяснить, что он делает на самом деле?
@raam получает только часть года
нет, мне нужно получать такие данные такжеid start end 1 201809 201812 id data 1 201809 1 201810 1 201811 1 201812
это для данных за месяц. По моей логике, я использую частоту как "MS"
Если данные отсортированы, вы можете попытаться найти первый экземпляр
end+1(например, 2006 и 2008), тогда вы можете получить данные до этого индекса - 1