Как создать столбец строк и сумм суммы в пандах?
Я проходил курс Академии Хан по статистике как немного обновленный из моих дней в колледже и как способ заставить меня ускорить участие в пандах и других научных Python.
У меня есть таблица, которая выглядит так из Академии Хана:
| Undergraduate | Graduate | Total
-------------+---------------+----------+------
Straight A | 240 | 60 | 300
-------------+---------------+----------+------
Not | 3,760 | 440 | 4,200
-------------+---------------+----------+------
Total | 4,000 | 500 | 4,500
Я хотел бы воссоздать эту таблицу с помощью панд. Конечно, я мог бы создать DataFrame, используя что-то вроде
"Graduate": {...},
"Undergraduate": {...},
"Total": {...},
Но это похоже на наивный подход, который быстро справится и просто не будет расширяться.
У меня есть не итоговая часть таблицы:
df = pd.DataFrame(
{
"Undergraduate": {"Straight A's": 240, "Not": 3_760},
"Graduate": {"Straight A's": 60, "Not": 440},
}
)
df
Я искал и нашел пару многообещающих вещей, таких как:
df['Total'] = df.sum(axis=1)
Но я не нашел ничего ужасно изящного.
Я нашел функцию crosstab
которая выглядит так, как будто она должна делать то, что я хочу, но, похоже, для этого мне пришлось бы создать dataframe, состоящий из 1/0 для всех этих значений, что кажется глупым, ve уже получил совокупность.
Я нашел несколько подходов, которые, как представляется, вручную создают новую итоговую строку, но кажется, что должен быть лучший способ, например:
totals(df, rows=True, columns=True)
или что-то.
Оказывается ли это в пандах, или мне нужно просто подбирать собственный подход?
Ответы
Ответ 1
Или в два этапа, используя предложенную вами функцию .sum()
(которая также может быть немного более читабельной):
import pandas as pd
df = pd.DataFrame( {"Undergraduate": {"Straight A's": 240, "Not": 3_760},"Graduate": {"Straight A's": 60, "Not": 440},})
#Total sum per column:
df.loc['Total',:]= df.sum(axis=0)
#Total sum per row:
df.loc[:,'Total'] = df.sum(axis=1)
Вывод:
Graduate Undergraduate Total
Not 440 3760 4200
Straight A 60 240 300
Total 500 4000 4500
Ответ 2
Смысл этого ответа состоит в том, чтобы предоставить линейное решение, а , а не, решение на месте.
Я использую append
, чтобы сложить Series
или DataFrame
вертикально. Он также создает copy
, чтобы я мог продолжать цепочку.
Я использую assign
, чтобы добавить столбец. Тем не менее, DataFrame
, над которым я работаю, находится в промежуточном пространстве. поэтому я использую lambda
в аргументе assign
, который говорит Pandas
применить его к вызывающему DataFrame
.
df.append(df.sum().rename('Total')).assign(Total=lambda d: d.sum(1))
Graduate Undergraduate Total
Not 440 3760 4200
Straight A 60 240 300
Total 500 4000 4500
Веселая альтернатива
Использует drop
с errors='ignore'
, чтобы избавиться от потенциально уже существующих Total
строк и столбцов.
Кроме того, все еще в очереди.
def tc(d):
return d.assign(Total=d.drop('Total', errors='ignore', axis=1).sum(1))
df.pipe(tc).T.pipe(tc).T
Graduate Undergraduate Total
Not 440 3760 4200
Straight A 60 240 300
Total 500 4000 4500
Ответ 3
Из исходных данных с использованием crosstab
, если вы просто основываетесь на своем вводе, вам просто нужно melt
до crosstab
s=df.reset_index().melt('index')
pd.crosstab(index=s['index'],columns=s.variable,values=s.value,aggfunc='sum',margins=True)
Out[33]:
variable Graduate Undergraduate All
index
Not 440 3760 4200
Straight A 60 240 300
All 500 4000 4500
Данные о игрушки
df=pd.DataFrame({'c1':[1,2,2,3,4],'c2':[2,2,3,3,3],'c3':[1,2,3,4,5]})
# before 'agg', I think your input is the result after 'groupby'
df
Out[37]:
c1 c2 c3
0 1 2 1
1 2 2 2
2 2 3 3
3 3 3 4
4 4 3 5
pd.crosstab(df.c1,df.c2,df.c3,aggfunc='sum',margins
=True)
Out[38]:
c2 2 3 All
c1
1 1.0 NaN 1
2 2.0 3.0 5
3 NaN 4.0 4
4 NaN 5.0 5
All 3.0 12.0 15
Ответ 4
Исходные данные:
>>> df = pd.DataFrame(dict(Undergraduate=[240, 3760], Graduate=[60, 440]), index=["Straight A's", "Not"])
>>> df
Out:
Graduate Undergraduate
Straight A 60 240
Not 440 3760
Вы можете использовать df.T
только для воссоздания этой таблицы:
>>> df_new = df.T
>>> df_new
Out:
Straight A Not
Graduate 60 440
Undergraduate 240 3760
После вычисления Total
строки и столбцов:
>>> df_new.loc['Total',:]= df_new.sum(axis=0)
>>> df_new.loc[:,'Total'] = df_new.sum(axis=1)
>>> df_new
Out:
Straight A Not Total
Graduate 60.0 440.0 500.0
Undergraduate 240.0 3760.0 4000.0
Total 300.0 4200.0 4500.0