Создание нового DataFrame Pandas из существующего - PullRequest
0 голосов
/ 11 апреля 2019

У меня есть фрейм данных pandas, который имеет данные на основе месяца следующим образом:

  df 

   id Month  val
   g1   Jan    1
   g1   Feb    5
   g1   Mar   61

Я хочу следующее:

Я хочу преобразовать фрейм данных в недельную структуру со столбцом месяца (заменен или нет) на все недели, которые могут произойти в этом месяце, поэтому выходные данные должны выглядеть следующим образом :( таким образом, 4 недели для каждого месяца)

   new_df 

     id  week  val
     g1     1    1
     g1     2    1
     g1     3    1
     g1     4    1
     g1     5    5
     g1     6    5
     g1     7    5
     g1     8    5
     g1     9   61
     g1    10   61
     g1    11   61
     g1    12   61

Я попытался использовать следующую функцию и применить ее к фрейму данных pandas, но это не работает:

SAMPLE CODE

      def myfun(mon):
        if mon == 'Jan':
           wk = list(range(1,5))
        elif mon == 'Feb':
           wk = list(range(5,9))
        else:
           wk = list(range(9,13))
        return wk

   df['week'] = df.apply(lambda row: myfun(row['Month']), axis=1)
   del df['Month']

Вывод, который я получаю, следующий: это не то, что я хочу:

       id    val         week
       g1    1     [1, 2, 3, 4]
       g1    5     [5, 6, 7, 8]
       g1    61  [9, 10, 11, 12]

Кроме того, есть ли хороший способ добиться этого?

Помощь будет очень ценится. Спасибо.

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

попробуйте это:

month={'Jan':1,'Feb':2,'March':3,'April':4,'May':5,'June':6,'July':7,'August':8,'Sept':9,'Oct':10,'Nov':11,'Dec':12}
new_df = pd.DataFrame(columns=['id', 'week', 'val']) # create a new dataframe
for index,row in df.iterrows(): # for each row in df
    month_num=(month[row[1]]-1)*4+1 # to get the starting week order from the dictionary "month"
    for i in range(4): # iterate four times 
        # append (add) the row with the week value to the new data frame
        new_df = new_df.append({'id':row[0],'week':month_num,'val':row[2]}, ignore_index=True)
        month_num+=1 # increment the week order
print(new_df)
1 голос
/ 12 апреля 2019

Мы можем использовать DataFrame.groupby и Dataframe.reindex с range(4).На выходе мы используем fillna с методом forwardfill ffill для замены NaN.

После этого мы конвертируем Month в формат даты и времени с pandas.to_datetime, поэтому мы можем отсортировать по месяцам.

Наконец, мы создаем столбец Week bij, получая индекс и добавляя 1, и удаляем столбец Month:

# extend index with 4 weeks for each month
df_new = pd.concat([
    d.reset_index(drop=True).reindex(range(4))
    for n, d in df.groupby('Month')
], ignore_index=True).fillna(method='ffill')

# Make a datetetime format from month columns
df_new["Month"] = pd.to_datetime(df_new.Month, format='%b', errors='coerce').dt.month

# Now we can sort it by month
df_new.sort_values('Month', inplace=True)

# Create a Week columns
df_new['Week'] = df_new.reset_index(drop=True).index + 1

# Drop month column since we dont need it anymore
df_new.drop('Month', axis=1, inplace=True)
df_new.reset_index(drop=True, inplace=True)

Что дает:

print(df_new)
    id   val  Week
0   g1   1.0     1
1   g1   1.0     2
2   g1   1.0     3
3   g1   1.0     4
4   g1   5.0     5
5   g1   5.0     6
6   g1   5.0     7
7   g1   5.0     8
8   g1  61.0     9
9   g1  61.0    10
10  g1  61.0    11
11  g1  61.0    12

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...