目前,我有一个结构类似这样的数据框
InvoiceNo Month Year Size
1 1 2014 7
2 1 2014 8
3 2 2014 11
4 3 2015 9
5 7 2015 8.5
以此类推...
我正在尝试创建一个函数,该函数将按年份对Dframe进行细分,然后按大小和月份进行分组,然后计算InvoiceNo,最后将该数据帧拆栈。
我一直在做的事情是这样的:
x = 2014
def Year_calc(df):
return df[df['Year'] == x].groupby(['Size','Month']).agg({'InvoiceNo': 'count'}).unstack(0).columns.droplevel(0).fillna(0)
然后是df2014 = Year_calc(df)
但是它返回以下输出:
Float64Index([], dtype='float64', name='Size')
有人能指出我做错了什么吗?
答案 0 :(得分:3)
使用groupby
,count
和unstack
:
res = df.groupby(['Year', 'Size', 'Month',]).InvoiceNo.count().unstack(0, fill_value=0)
res
Year 2014 2015
Size Month
7.0 1 1 0
8.0 1 1 0
8.5 7 0 1
9.0 3 0 1
11.0 2 1 0
或者,等效于pivot_table
:
res = df.pivot_table(index=['Size', 'Month'],
columns='Year',
values='InvoiceNo',
aggfunc='count',
fill_value=0)
Year 2014 2015
Size Month
7.0 1 1 0
8.0 1 1 0
8.5 7 0 1
9.0 3 0 1
11.0 2 1 0
比较如下:
res[2014] > res[2015]
或者,只计算所需的年份:
(df[df.Year.eq(2014)]
.groupby(['Size', 'Month'])
.InvoiceNo
.count()
.unstack(1, fill_value=0))
Month 1 2
Size
7.0 1 0
8.0 1 0
11.0 0 1
答案 1 :(得分:1)
df.apply
会将行或列作为Series对象传递-取决于您指定的轴。它不会传递整个数据帧。
如果要将功能应用于整个数据框,df2014 = Year_calc(df)
怎么样?
您还应该考虑将year作为参数传递给函数-这样可以很清楚year_calc函数在做什么。
答案 2 :(得分:0)
这是输入数据:
import pandas as pd
d = {'InvoiceNo':[1,2,3,4,5],'Month':[1,1,2,3,7],'Year':[2014,2014,2014,2015,2015],'Size':[7,8,11,9,8.5]}
df = pd.DataFrame(data = d)
解决方案1:
使用先前的答案和您提供的元素,这是我设法编写的功能:
def Year_calc(data, year):
# grouping the by Size and month
t1 = data.loc[data.Year == year].groupby(['Size','Month'])
#count the number of Invoice for the given year
t2 = t1.InvoiceNo.count().unstack(0, fill_value=0)
return t2
这是年份= 2014的返回表:
Size 7.0 8.0 11.0
Month
1 1 1 0
2 0 0 1
解决方案2 由于您删除了年份作为参数,因此似乎不需要做任何调整,您可以先按年份选择行,然后再进行分组,也可以按年份,月份,大小进行分组,然后选择与所需年份相对应的行。>
def Year_calc(data):
# grouping the by Year, Size and month
t1 = data.groupby(['Year','Month','Size'])
#count the number of Invoice for the given year
t2 = t1.InvoiceNo.count().unstack(2, fill_value=0)
return t2
未经过滤的输出为:
Size 7.0 8.0 8.5 9.0 11.0
Year Month
2014 1 1 1 0 0 0
2 0 0 0 0 1
2015 3 0 0 0 1 0
7 0 0 1 0 0
假设您需要2015年的数据,然后键入:
tdf = Year_calc(data = df)
tdf.xs(2015)
# or
test.loc[(2015,),:]
返回的结果:
Size 7.0 8.0 8.5 9.0 11.0
Month
3 0 0 0 1 0
7 0 0 1 0 0
请检查这篇文章中的多索引切片:here
希望这会有所帮助!