Невозможно удалить строки с пустым списком, принимая среднее значение других списков - PullRequest
1 голос
/ 24 мая 2019

У меня есть временной ряд df, который имеет 2 столбца. Я пытаюсь отбросить все пустые списки из столбцов yearly_cost, взяв среднее значение списков, содержащих числа с плавающей запятой, для создания единственного значения для каждого отдельного дня. В столбце date имеется несколько значений для одной и той же даты, и поэтому я пытаюсь объединить все строки на основе этой даты. df выглядит так:

    date        yearly_cost
0   2009-01-01  []
1   2009-01-02  [409.45,294.33,394.56]
2   2009-01-03  [403.45,175.30,323.67]
3   2009-01-01  [456.34,355.3,493.5]
4   2009-01-02  []
5   2009-01-03  [295.39, 439.23]

В некоторые дни будет несколько списков, и поэтому мне нужно взять среднее значение по обоим спискам, чтобы создать одно значение.

Я попытался использовать .dropna(), np.nanmean() и усреднить списки с ts.yearly_cost = [np.mean(i) if isinstance(i, list) else i for i in ts.yearly_cost] с конкатенацией по дате. с .set_index('date').mean(axis=1).reset_index(name='Yearly_Cost'), который работал для временных рядов в прошлом без пустых списков.

Я хочу, чтобы конечный результат выглядел так:

date        yearly_cost
0   2009-01-01  435.05
1   2009-01-02  366.11
2   2009-01-03  327.408

Любая помощь с этим будет принята с благодарностью. Спасибо

Ответы [ 3 ]

4 голосов
/ 24 мая 2019

Если в столбце yearly_cost есть списки, то сначала свести их, а затем объединить mean:

import ast
#necessary if string repr of lists
#df['yearly_cost'] = df['yearly_cost'].apply(ast.literal_eval)

from itertools import chain

df = pd.DataFrame({
    'yearly_cost' : list(chain.from_iterable(df['yearly_cost'].tolist())), 
    'date' : df['date'].values.repeat(df['yearly_cost'].str.len())
})

df = df.groupby('date', as_index=False)['yearly_cost'].mean()
print (df)
         date  yearly_cost
0  2009-01-01   435.046667
1  2009-01-02   366.113333
2  2009-01-03   327.408000

Другое решение:

s = pd.DataFrame(df['yearly_cost'].values.tolist(), index=df['date']).stack()
df = s.mean(level=0).reset_index(name='yearly_cost')
print (df)
         date  yearly_cost
0  2009-01-02   366.113333
1  2009-01-03   327.408000
2  2009-01-01   435.046667
3 голосов
/ 24 мая 2019

IIUC

Удалить пустой список, преобразовав тип в bool.

df=df[df.yearly_cost.astype(bool)].copy()

После удаления пустого списка вы можете сделать groupby

df.groupby('date')['yearly_cost'].apply(lambda x : np.mean(x.sum()))
0 голосов
/ 24 мая 2019

groupby.sum и np.mean

Сумма объединит списки.

df.groupby('date').yearly_cost.sum().apply(np.mean)

date
2009-01-01    435.046667
2009-01-02    366.113333
2009-01-03    327.408000
Name: yearly_cost, dtype: float64

Если это строки

from ast import literal_eval

df.yearly_cost.apply(literal_eval).groupby(df.date).sum().apply(np.mean)

ALT

df.groupby('date').yearly_cost.apply(lambda x: np.concatenate([*x]).mean())

Факторизация

i, u = df.date.factorize()
j = i.repeat([*map(len, df.yearly_cost)])
v = np.concatenate(df.yearly_cost)

c = np.bincount(j)
s = np.bincount(j, v)
pd.Series(s / c, u)

2009-01-01    435.046667
2009-01-02    366.113333
2009-01-03    327.408000
dtype: float64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...