Простая кросс-табуляция в pandas
Я наткнулся на pandas, и он идеально подходит для простых вычислений, которые я хотел бы сделать. У меня есть фон SAS и я думал, что он заменит proc freq - похоже, он будет масштабироваться в зависимости от того, что я могу сделать в будущем. Тем не менее, я просто не могу показаться, что у меня голова вокруг простой задачи (я не уверен, что я должен смотреть на pivot/crosstab/indexing
- должен ли я иметь Panel
или DataFrames
и т.д....). Может ли кто-нибудь дать мне несколько указаний о том, как сделать следующее:
У меня есть два CSV файла (один для 2010 года, один для 2011 года - простые транзакционные данные) - столбцы - это категория и количество
2010
AB,100.00
AB,200.00
AC,150.00
AD,500.00
2011
AB,500.00
AC,250.00
AX,900.00
Они загружаются в отдельные объекты DataFrame.
То, что я хотел бы сделать, это получить категорию, сумму категории и частоту категории, например:
2010
AB,300.00,2
AC,150.00,1
AD,500.00,1
2011
AB,500.00,1
AC,250.00,1
AX,900.00,1
Я не могу решить, должен ли я использовать pivot/crosstab/groupby/an index
и т.д. Я могу получить либо сумму, либо частоту - я не могу получить оба... Это становится немного сложнее, потому что я хотел бы сделать это месяц за месяцем, но я думаю, что если кто-то было бы так любезно указать мне на правильную технику/направление, в котором я смогу оттуда.
Ответы
Ответ 1
Предположим, что у вас есть файл с именем 2010.csv с содержимым
category,value
AB,100.00
AB,200.00
AC,150.00
AD,500.00
Затем, используя возможность применения нескольких функций агрегации, следующих за groupby, вы можете сказать:
import pandas
data_2010 = pandas.read_csv("/path/to/2010.csv")
data_2010.groupby("category").agg([len, sum])
Вы должны получить результат, который выглядит примерно так:
value
len sum
category
AB 2 300
AC 1 150
AD 1 500
Обратите внимание, что Wes, скорее всего, придет, чтобы указать, что сумма оптимизирована и что вы, вероятно, должны использовать np.sum.
Ответ 2
v0.21
ответ
Используйте pivot_table
с параметром index
:
df.pivot_table(index='category', aggfunc=[len, sum])
len sum
value value
category
AB 2 300
AC 1 150
AD 1 500
<= v0.12
Это можно сделать с помощью pivot_table
для заинтересованных:
In [8]: df
Out[8]:
category value
0 AB 100
1 AB 200
2 AC 150
3 AD 500
In [9]: df.pivot_table(rows='category', aggfunc=[len, np.sum])
Out[9]:
len sum
value value
category
AB 2 300
AC 1 150
AD 1 500
Обратите внимание, что столбцы результатов иерархически индексируются. Если у вас несколько столбцов данных, вы получите такой результат:
In [12]: df
Out[12]:
category value value2
0 AB 100 5
1 AB 200 5
2 AC 150 5
3 AD 500 5
In [13]: df.pivot_table(rows='category', aggfunc=[len, np.sum])
Out[13]:
len sum
value value2 value value2
category
AB 2 2 300 10
AC 1 1 150 5
AD 1 1 500 5
Основная причина использования __builtin__.sum
vs. np.sum
заключается в том, что вы получаете обработку NA из последней. Вероятно, можно перехватить встроенный Python, сейчас заметьте.