2016-10-28 2 views
8

У меня есть dataframe с колоннами, как:Панда: Mean столбцов с одинаковыми именами

['id','name','foo1', 'foo1', 'foo1', 'foo2','foo2', 'foo3'] 

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

['id','name','foo1', 'foo2','foo3'] 

Здесь столбец foo1 будет средним из трех столбцов с именем foo1 в исходном фрейме данных, foo2 будет средним из двух столбцов с именем foo2 и foo3 будет просто foo3

Примечание: id и имя не является числовым, и я должен их хранить.

+2

Установить индекс на имя и имя, groupby col имена, mean(), индекс сброса должен сделать это – Boud

+0

Но что делать, если у меня есть много нечисловых столбцов, таких как id и name? Можно ли установить индекс всеми нечисловыми столбцами? – user3635284

ответ

5

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

Я увидел несколько комментариев по вашему вопросу и попытался дать вам разные способы достижения цели. (Решение (3) - это лучшее, что я нашел!)

(1) Быстрое решение. Если у вас очень ограниченные столбцы, которые не являются числовыми, и имеют собственные уникальные имена, например, столбцы id и name. Что вы можете сделать, это:

Первого набор индекс ['id', 'name'], чтобы сохранить их,

df = df.set_index(['id', 'name']) 

затем использовать DataFrame.groupby функции columns, установите axis=1 (итерацию по каждой колонке), применяются mean функций для каждой группы.

df.groupby(by=df.columns, axis=1).mean() 

И, наконец, сбросить индекс для восстановления ['id', 'name'] столбцы

df = df.reset_index() 

Вот пример кода:

In [35]: df = pd.DataFrame([['001', 'a', 1, 10, 100, 1000], ['002', 'b', 2, 20, 200, 2000]], columns=['id', 'name', 'c1', 'c2', 'c2', 'c3'], index=list('AB')) 

In [36]: df = df.set_index(['id', 'name']) 

In [37]: df = df.groupby(by=df.columns, axis=1).mean() 

In [38]: df = df.reset_index() 

In [39]: df 
Out[39]: 
    id name c1 c2 c3 
0 001 a 1 55 1000 
1 002 b 2 110 2000 

(2) Комплексное решение.Если у вас есть много столбцов, которые не являются числовыми и уникальное имя, что вы можете сделать, это:

Первый транспонировать вы dataframe,

df2 = df.transpose() 

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

df2 = df2.groupby(by=df2.index, axis=0).apply(lambda g: g.mean() if isinstance(g.iloc[0,0], numbers.Number) else g.iloc[0]) 

И, наконец, переставлять обратно:

df = df2.transpose() 

Вот пример кода:

In [98]: df = pd.DataFrame([['001', 'a', 1, 10, 100, 1000], ['002', 'b', 2, 20, 200, 2000]], columns=['id', 'name', 'c1', 'c2', 'c2', 'c3'], index=list('AB')) 

In [99]: df2 = df.transpose() 

In [100]: df2 = df2.groupby(by=df2.index, axis=0).apply(lambda g: g.mean() if isinstance(g.iloc[0,0], numbers.Number) else g.iloc[0]) 

In [101]: df3 = df2.transpose() 

In [102]: df3 
Out[102]: 
    c1 c2 c3 id name 
A 1 55 1000 001 a 
B 2 110 2000 002 b 

In [103]: df 
Out[103]: 
    id name c1 c2 c2 c3 
A 001 a 1 10 100 1000 
B 002 b 2 20 200 2000 

Вы должны import numbers

Другие примечания:

(3) Все в одном! Это решение является лучшим я нашел:

df.groupby(by=df.columns, axis=1).apply(lambda g: g.mean(axis=1) if isinstance(g.iloc[0,0], numbers.Number) else g.iloc[:,0]) 

Я пытался справиться с каждой группой для ООН-транспонированная групп, то есть

df.groupby(by=df.columns, axis=1).apply(gf) 

И

gf = lambda g: g.mean(axis=1) if isinstance(g.iloc[0,0], numbers.Number) else g.iloc[:,0] 

мне не удалось раньше, потому что я не осторожно передаю ось. Вы должны установить axis=1 для функции mean и вернуть столбцы для нечисловых групп.

Спасибо!

+0

Это дает мне ошибку в столбцах «no numeric types to aggregate»: id: object, name: object, foo1: float64, foo1: float64, foo1: float64, foo2: float64, foo2: float64, foo3: float64 – user3635284

+0

Извини за это. Я починил это. – rojeeer

+0

Спасибо! Решение 3 действительно то, что мне нужно, проверка, чтобы проверить, является ли нулевое число числом, я не мог этого сделать. Спасибо! – user3635284

Смежные вопросы