按for循环分组

时间:2019-07-31 16:43:38

标签: python pandas group-by pandas-groupby

我有一个具有以下结构的数据框:

df= pd.DataFrame({"Origin": ['A','A','A','A','B','B','B'],"Name":["John","Bob","John","John","Bob","Elvis","John"],"Year":[2015,2015,2015,2015,2015,2016,2016]})

Origin |Name | Year
    A   John    2015
    A   Bob     2015
    A   John    2015
    A   John    2015
    B   Bob     2015
    B   Elvis   2016
    B   John    2016

我正在尝试按以下方式重新整理数据:每年,我要计算每个起源的每个名称的行数。在栏名和索引中的名称一起提出起源和年联合。 此处的预期输出应为:

index  | A_2015 | A_2016 | B_2015 | B 2016 |
--------------------------------------------
John   | 3      | 0      | 0      |  1
Bob    | 1      | 0      | 1      |  0
Elvis  | 0      | 0      | 0      |  1

原点可以分隔在不同的数据框中,这对我来说并不重要(我当前的代码正在将其分割)。
我的代码正在运行,但是如果发现它不雅,因为我将for循环和group_by结合在一起。这是我的镜头,我想知道是否有更好的方法来执行此转换。

dfTotalA = pd.DataFrame()
dfTotalB = pd.DataFrame()
for Year in TotalData.Year.unique():
    df = TotalData.query("(Origin == 'A') & (YearHit == @Year)")[["Origin","Name"]].groupby('Name').Origin.size().to_frame(name='A_'+str(Year))
    dfTotalA= pd.concat([dfTotal,df1],sort=False,axis=1)
    df2 = TotalData.query("(Origin == 'B') & (YearHit == @Year)")[["Origin","Name"]].groupby('Name').Origin.size().to_frame(name='B_'+str(Year))
    dfTotalB= pd.concat([dftotalB,df2],sort=False,axis=1)
Completedf = pd.concat(dfTotalA,dftotalB],sort=False,axis=1)
Completedf.fillna(0,inplace=True)

2 个答案:

答案 0 :(得分:1)

一种方法:

new_df = (df.groupby(['Origin', 'Year'])
   .Name
   .value_counts()
   .unstack(['Origin'], fill_value=0)
   .unstack('Year', fill_value=0)
)

给出:

Origin    A         B     
Year   2015 2016 2015 2016
Name                      
Bob       1    0    1    0
Elvis     0    0    0    1
John      3    0    0    1

然后您可以使用以下方式重命名列:

new_df.columns = [f'{a}_{b}' for a,b in new_df.columns]

答案 1 :(得分:1)

我们可以使用count创建一个GroupBy.transform列。然后pivot_table。最后展平我们的MultiIndex列:

df['cnt'] = df.groupby(['Origin', 'Name'])['Year'].transform('count')

piv = df.pivot_table(index='Name', columns=['Origin', 'Year'], fill_value=0)
piv.columns = [f'{c[1]}_{c[2]}'for c in piv.columns]

输出

       A_2015  B_2015  B_2016
Name                         
Bob         1       1       0
Elvis       0       0       1
John        3       0       1