Фикс групповой длины в пандах - PullRequest
1 голос
/ 18 апреля 2019

У меня есть сгруппированный по Pandas датафрейм:

id    date    temperature
1  2011-9-12   12
   2011-9-18   12
   2011-9-19   12
2  2011-9-12   15
3  2011-9-12   15
   2011-9-16   15

Здесь каждый идентификатор имеет разное количество записей температуры.

Я хочу исправить их, скажем, среднее количество записей на один идентификатор (скажем, 3). Если некоторые записи отсутствуют, сначала я хочу поставить нули.

т.е. Мой окончательный фрейм данных должен быть:

id    temperature
1     12
      12
      12
2     0
      0
      15
3     0
3     15
3     15

Мне нужно настроить количество записей на один идентификатор на некоторое число, которое также может быть средним числом записей на один идентификатор. Как получить среднее значение?

Ответы [ 2 ]

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

Мы можем использовать reindex с range(3) при доступе к элементам группировки. После этого мы sort_values и установили NaN в качестве первой позиции, чтобы мы могли fillna как 0.

df_new = pd.concat([
    d[['id', 'temperature']].reset_index(drop=True).reindex(range(3)).sort_values('id', na_position='first')
    for _, d in df.groupby('id')
], ignore_index=True)

df_new['id'].fillna(method='bfill', inplace=True)
df_new['temperature'].fillna(0, inplace=True)

print(df_new)
    id  temperature
0  1.0         12.0
1  1.0         12.0
2  1.0         12.0
3  2.0          0.0
4  2.0          0.0
5  2.0         15.0
6  3.0          0.0
7  3.0         15.0
8  3.0         15.0

Примечание у вас есть id и date в качестве индекса, поэтому первый запуск:

df.reset_index(inplace=True)
1 голос
/ 18 апреля 2019

Просто используя stack и unstack

df.groupby(level=0)['temperature'].\
      apply(list).\
         apply(pd.Series).iloc[:,:3].\
                 apply(lambda x : pd.Series(sorted(x,key=pd.notnull)),1).\
                   fillna(0).stack().reset_index(level=0)
Out[523]: 
   id     0
0   1  12.0
1   1  12.0
2   1  12.0
0   2   0.0
1   2   0.0
2   2  15.0
0   3   0.0
1   3  15.0
2   3  15.0

Numpy решение для ускорения

s=df.groupby(level=0)['temperature'].apply(list)
s1=s.tolist()
arr = np.zeros((len(s1),3),int)
lens = [3-len(l) for l in s1]
mask = np.arange(3) >=np.array(lens)[:,None]
arr[mask] = np.concatenate(s1)
pd.DataFrame({'id':s.index.repeat(3),'temperature':arr.ravel()})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...