Основная идея состоит в том, что вы можете группировать имена ваших столбцов и выполнять операции для каждой группы.
Я увидел несколько комментариев по вашему вопросу и попытался дать вам разные способы достижения цели. (Решение (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
и вернуть столбцы для нечисловых групп.
Спасибо!
Установить индекс на имя и имя, groupby col имена, mean(), индекс сброса должен сделать это – Boud
Но что делать, если у меня есть много нечисловых столбцов, таких как id и name? Можно ли установить индекс всеми нечисловыми столбцами? – user3635284