Как уменьшить временную сложность или повысить эффективность программы, находя промежутки месяца, используя питонов

1

Ввод такой вот

Data    Id
201505  A
201507  A
201509  A
200001  B
200001  C
200002  C
200005  C

Я обнаружил пробелы в датах и использовал это. Но для завершения функции для больших данных требуется слишком много времени, как я могу уменьшить временную сложность

#convert to datetimes
month['data'] = pd.to_datetime(month['data'], format='%Y%m')
#resample by start of months with asfreq
mdf = month.set_index('data').groupby(['series_id','symbol'])['series_id'].resample('MS').asfreq().rename('val').reset_index()
x = mdf['val'].notnull().rename('g')
#create index by cumulative sum for unique groups for consecutive NaNs
mdf.index = x.cumsum()
#filter only NaNs row and aggregate first, last and count.
mdf = (mdf[~x.values].groupby(['series_id','symbol','g'])['data'].agg(['first','last','size']).reset_index(level=2, drop=True).reset_index())

print mdf

 Id      first       last  size
0  A 2015-06-01 2015-06-01     1
1  A 2015-08-01 2015-08-01     1
2  B 2000-02-01 2000-02-01     1
3  C 2003-03-01 2003-04-01     2

Как я могу уменьшить временную сложность или какой-либо другой способ найти промежутки времени.

  • 0
    Что вы имеете в виду под пробелами
  • 0
    пропущенные месяцы для идентификатора, например, для идентификатора А пропущен месяц с 201505 по 201507, пропущенный месяц равен 201506
Показать ещё 4 комментария
Теги:
pandas

2 ответа

1

Поэтому, используя немного идею @RushabhMehta, вы можете pd.DateOffset создать выходной блок данных. Ваш входной фреймворк называется month, с данными столбца 'и' series_id ', в соответствии с вашим кодом. Вот идея:

month['data'] = pd.to_datetime(month['data'], format='%Y%m')
month = month.sort_values(['series_id','data'])
# create mdf with the column you want
mdf = pd.DataFrame({'Id':month.series_id, 'first':month.data + pd.DateOffset(months=1), 
                    'last': (month.groupby('series_id').data.shift(-1) - pd.DateOffset(months=1))})

Обратите внимание, как столбец "последний" создается, используя groupby, shift значение и вычитать в месяц с pd.DateOffset(months=1). Теперь выберите только строки, в которых дата в "первом" находится перед "последним", и создайте размер столбца, например:

mdf = mdf.loc[mdf['first'] <= mdf['last']]
mdf['size'] = (mdf['last']- mdf['first']).astype('timedelta64[M]')+1

mdf выглядит так:

       first Id       last  size
0 2015-06-01  A 2015-06-01   1.0
1 2015-08-01  A 2015-08-01   1.0
3 2000-02-01  B 2000-02-01   1.0
6 2000-03-01  C 2000-04-01   2.0

Просто нужно изменить порядок столбцов и reset_index если хотите.

  • 0
    Я получаю сообщение об ошибке mdf = mdf.loc [mdf.first <= mdf.last] в этой функции, которая является ключевой ошибкой true.
  • 0
    @raam действительно, это потому, что 'first' и 'last' - это имена столбцов, которые я не должен использовать таким образом. Попробуйте mdf.loc[mdf['first'] <= mdf['last']] должно работать
Показать ещё 16 комментариев
1

Сделанные предположения следующие:

  • Все значения в столбце данных уникальны, даже для групп
  • Данные в столбце данных являются целыми числами
  • Сначала данные сортируются по группам, а затем по значению.

Вот мой алгоритм (mdf - это вход df):

import pandas as pd
df2 = pd.DataFrame({'Id':mdf['Id'],'First':mdf['Data']+1,'Last':(mdf['Data']-1).shift(-1)})
df2 = df2.groupby('Id').apply(lambda g: g[g['Data'] != g['Data'].max()]).reset_index(drop=True)
print(df2[~df['First'].isin(mdf['Data'])&~df['Last'].isin(mdf['Data'])])
  • 0
    данные в столбцах имеют тип datetime с форматом = '% Y% m', а также ваш код выдает ошибку lambda x: op (x, rvalues)) TypeError: должен быть str, а не int
  • 0
    что бери данные в лямду показывает ошибку
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню