#python-3.x #pandas
#python-3.x #pandas
Вопрос:
Использование pandas 0.19.0. Следующий код воспроизведет проблему:
In [1]: import pandas as pd
import numpy as np
In [2]: df = pd.DataFrame({'c1' : list('AAABBBCCC'),
'c2' : list('abcdefghi'),
'c3' : np.random.randn(9),
'c4' : np.arange(9)})
df
Out[2]: c1 c2 c3 c4
0 A a 0.819618 0
1 A b 1.764327 1
2 A c -0.539010 2
3 B d 1.430614 3
4 B e -1.711859 4
5 B f 1.002522 5
6 C g 2.257341 6
7 C h 1.338807 7
8 C i -0.458534 8
In [3]: def myfun(s):
"""Function does practically nothing"""
req = s.values
return pd.Series({'mean' : np.mean(req),
'std' : np.std(req),
'foo' : 'bar'})
In [4]: res = df.groupby(['c1', 'c2'])['c3'].apply(myfun)
res.head(10)
Out[4]: c1 c2
A a foo bar
mean 0.819618
std 0
b foo bar
mean 1.76433
std 0
c foo bar
mean -0.53901
std 0
B d foo bar
И, конечно, я ожидаю этого:
Out[4]: foo mean std
c1 c2
A a bar 0.819618 0
b bar 1.76433 0
c bar -0.53901 0
B d bar 1.43061 0
Pandas автоматически преобразует серию в фрейм данных, когда возвращается функцией, которая применяется к ряду или фрейму данных. Почему поведение функций, применяемых к группам, отличается?
Я ищу ответ, который приведет к желаемому результату. Бонусные баллы за объяснение разницы в поведении между pandas.Series.apply
or pandas.DataFrame.apply
и pandas.core.groupby.GroupBy.apply
Комментарии:
1. Однако то, что вы пытаетесь сделать, принципиально отличается: вы возвращаете серию, а «столбцы», которые вы определяете в dict, станут индексом, поскольку эти значения индекса не существуют, он создает их как новый уровень индекса. Если вы сделали это:
res = df.groupby(['c1', 'c2'])['c3'].apply(lambda x: pd.DataFrame({'mean' : [np.mean(x)], 'std' : [np.std(x)], 'foo' : 'bar'}))
тогда это будет работать по желанию2. @EdChum Спасибо Ed. Теперь я понял. Я был слишком сонным, чтобы увидеть это сам.
3. На самом деле, @EdChum я попытался вернуть фрейм данных, созданный с помощью того же словаря. Это тоже не сработало. Это то, что меня сбило с толку…
Ответ №1:
простым решением было бы unstack
df = pd.DataFrame({'c1' : list('AAABBBCCC'),
'c2' : list('abcdefghi'),
'c3' : np.random.randn(9),
'c4' : np.arange(9)})
def myfun(s):
"""Function does practically nothing"""
req = s.values
return pd.Series({'mean' : np.mean(req),
'std' : np.std(req),
'foo' : 'bar'})
res = df.groupby(['c1', 'c2'])['c3'].apply(myfun)
res.unstack()
Комментарии:
1. Да! Индекс интегрирован! Очевидно, что это уровень индекса. Мне нужно спать больше, чем 4 часа в сутки. Спасибо piRSquared, оценил.