Заполнение даты, о которой нет записи в данных журнала, пандами

#python #pandas #dataframe

Вопрос:

У меня есть таблица журналов, такая как

 Category   User_id  0402_sales   0403_sales  0405_sales 
  Wine      999999      5            3           0  
  Beer      999999      5            0           0
  Beer      888888      3            2           3
 

Я могу сделать только таблицу, которая записана в журнале, но я хочу заполнить дату даже без журнала.

Например, наш журнал начинается с 4/1 и заканчивается на 4/6, мне нужна заполненная таблица дат, как показано ниже.

 Category   User_id  0401_sales   0402_sales   0403_sales  0404_sales 0405_sales  0406_sales 
  Wine      999999      0            5           3            0          0           0
  Beer      999999      0            5           0            0          0           0
  Beer      888888      0            3           2            0          3           0
 

Суть в том, чтобы проверить, существует ли дата с первого по последний день, если нет, добавьте столбец даты со значениями 0

Ответ №1:

Переиндексируйте, ось=столбцы. Если вы хотите, чтобы он автоматизировал новые символы, которые будут использоваться для переиндексации, я бы использовал регулярное выражение для извлечения, вычисления минимального и максимального значений, использования диапазона pythons для заполнения, а затем для переиндексации. Это даст вам минус несколько столбцов. Используйте combine_first, чтобы исправить это. Код ниже

 new_index=[f"0{num}_sales" for num in list(np.arange(df.columns.str.extract('(d )').dropna().min()[0].astype(int)-1,df.columns.str.extract('(d )').dropna().max()[0].astype(int) 2))]
df=df.reindex(new_index, axis="columns").fillna(0).combine_first(df)



     0401_sales  0402_sales  0403_sales  0404_sales  0405_sales  0406_sales  
0         0.0           5           3         0.0           0         0.0   
1         0.0           5           0         0.0           0         0.0   
2         0.0           3           2         0.0           3         0.0   

  Category   User_id  
0     Wine  999999.0  
1     Beer  999999.0  
2     Beer  888888.0 
 

Комментарии:

1. Спасибо, я знаю это решение, но если журнал начинается с 1/1 и заканчивается 12/31, если есть способ автоматического заполнения даты

2. Спасибо, так как вы впервые ответили на мой вопрос, и ваш ответ может работать в моей среде, я приму ваш ответ

Ответ №2:

Вы можете создать новый индекс и перестроить столбцы с его помощью:

 new_dates = [f"0{num}_sales" for num in range(401, 407)]

df = df.set_index(['Category', 'User_id'])

df.reindex(columns = new_dates, fill_value = 0).reset_index()

  Category  User_id  0401_sales  0402_sales  0403_sales  0404_sales  0405_sales  0406_sales
0     Wine   999999           0           5           3           0           0           0
1     Beer   999999           0           5           0           0           0           0
2     Beer   888888           0           3           2           0           3           0
 

Ответ №3:

Вы можете создать список дат с помощью pandas.date_range(). Затем используйте strftime() для преобразования списка дат в нужный формат.

 columns = [day   '_sales' for day in pd.date_range(start='2010-4-1', end='2010-4-10').strftime('%m%d')]
 

После этого удалите даты, из columns которых уже df.columns есть . И назначьте новым столбцам значение по умолчанию 0.

 columns = list(set(columns) - set(df.columns))
df[columns] = 0
 

Наконец, измените порядок столбцов с датой.

 df = df.reindex(df.columns.tolist()[:2]   sorted(df.columns.tolist()[2:]), axis=1)
# or
df = df[df.columns.tolist()[:2]   sorted(df.columns.tolist()[2:])]