循环中轴= 1的Concat数据帧/系列

时间:2019-09-15 01:08:11

标签: python pandas dataframe

我有一个电子邮件发件人的数据框,如下所示。 我正在尝试获得一个数据框作为输出,该数据框是每个eac人员每月发送的电子邮件数量。 我希望索引是月末,列是人。 我能够构建它,但是有两个问题:

首先,我:正在使用多个pd.concat语句(所有df_temps),它们很丑陋且无法扩展。 有没有办法将其置于for循环中或以其他方式循环至前n个人?

第二,虽然将所有数据正确地放在一起,但是索引中存在间断。 最后一行是1999-01-31,最后一行是2000-01-31。 是否有选择或方法可以在几个月之间获得NaN?

以下代码:

import pandas as pd

df_in = pd.DataFrame({
'sender':['Able Boy','Able Boy','Able Boy','Mark L. Taylor','Mark L. Taylor',
    'Mark L. Taylor','scott kirk','scott kirk','scott kirk','scott kirk',
    'Able Boy','Able Boy','james h. madison','james h. madison','james h. madison',
    'james joyce','scott kirk','james joyce','james joyce','james joyce',
    'james h. madison','Able Boy'],
'receiver':['Toni Z. Zapata','Mark Angel','scott kirk','paul a boyd','michelle fam',
    'debbie bradford','Mark Angel','Johnny C. Cash','Able Boy','Mark L. Taylor',
    'jenny chang','julie s. smith', 'scott kirk', 'tiffany r.','Able Boy',
    'Mark Angel','Able Boy','julie s. smith','jenny chang','debbie bradford',
    'Able Boy','Toni Z. Zapata'],
'time':[911929000000,911929000000,910228000000,911497000000,911497000000,
    911932000000,914261000000,914267000000,914269000000,914276000000,
    914932000000,915901000000,916001000000,916001000000,916001000000,
    947943000000,947943000000,947943000000,947943000000,947943000000,
    916001000000,911929100000],
'email_ID':['<A34E5R>','<A34E5R>','<B34E5R>','<C34E5R>','<C34E5R>',
    '<C36E5R>','<C36E5A>','<C36E5B>','<C36E5C>','<C36E5D>',
    '<D000A0>','<D000A1>','<D000A2>','<D000A2>','<D000A2>',
    '<D000A3>','<D000A3>','<D000A3>','<D000A3>','<D000A3>',
    '<D000A4>','<A34E5S>']
})
df_in['time'] = pd.to_datetime(df_in['time'],unit='ms')

df_1 = df_in.copy()
df_1['number'] = 1

df_2 = df_1.drop_duplicates(subset="email_ID",keep="first",inplace=False)\
        .reset_index()

df_3 = df_2.drop(columns=['index','receiver','email_ID'],inplace=False)

df_6 = df_3.groupby(['sender',pd.Grouper(key='time',freq='M')]).sum()

df_6_squeezed = df_6.squeeze()

df_grp_1 = df_3.groupby(['sender']).count()
df_grp_1.sort_values(by=['number'],ascending=False,inplace=True)

toppers = list(df_grp_1.index.array)

df_temp_1 = df_6_squeezed[toppers[0]]
df_temp_2 = df_6_squeezed[toppers[1]]
df_temp_3 = df_6_squeezed[toppers[2]]
df_temp_4 = df_6_squeezed[toppers[3]]
df_temp_5 = df_6_squeezed[toppers[4]]

df_temp_1.rename(toppers[0],inplace=True)
df_temp_2.rename(toppers[1],inplace=True)
df_temp_3.rename(toppers[2],inplace=True)
df_temp_4.rename(toppers[3],inplace=True)
df_temp_5.rename(toppers[4],inplace=True)

df_concat_1 = pd.concat([df_temp_1,df_temp_2],axis=1,sort=False)
df_concat_2 = pd.concat([df_concat_1,df_temp_3],axis=1,sort=False)
df_concat_3 = pd.concat([df_concat_2,df_temp_4],axis=1,sort=False)
df_concat_4 = pd.concat([df_concat_3,df_temp_5],axis=1,sort=False)
print("\nCONCAT  (df_concat_4):")
print(df_concat_4)
print(type(df_concat_4))

1 个答案:

答案 0 :(得分:3)

计算 month_end 后,请考虑pivot_table(请参阅@Root的answer)。另外,使用reindex填写缺少的月份。通常在熊猫中,分组汇总(例如每月的发件人数量)不需要循环或临时帮助程序数据帧。

from pandas.tseries.offsets import MonthEnd

df_in['month_end'] = (df_in['time'] + MonthEnd(0)).dt.normalize()

agg_df = (df_in.pivot_table(index='month_end', columns='sender', values='time', aggfunc='count')
               .reindex(pd.date_range('1998-01-01', '2000-01-31', freq='m').values, axis='index')
               .fillna(0)                
          )

输出

print(agg_df)  
# sender      Able Boy  Mark L. Taylor  james h. madison  james joyce  scott kirk
# month_end                                                                      
# 1998-01-31       0.0             0.0               0.0          0.0         0.0
# 1998-02-28       0.0             0.0               0.0          0.0         0.0
# 1998-03-31       0.0             0.0               0.0          0.0         0.0
# 1998-04-30       0.0             0.0               0.0          0.0         0.0
# 1998-05-31       0.0             0.0               0.0          0.0         0.0
# 1998-06-30       0.0             0.0               0.0          0.0         0.0
# 1998-07-31       0.0             0.0               0.0          0.0         0.0
# 1998-08-31       0.0             0.0               0.0          0.0         0.0
# 1998-09-30       0.0             0.0               0.0          0.0         0.0
# 1998-10-31       0.0             0.0               0.0          0.0         0.0
# 1998-11-30       4.0             3.0               0.0          0.0         0.0
# 1998-12-31       1.0             0.0               0.0          0.0         4.0
# 1999-01-31       1.0             0.0               4.0          0.0         0.0
# 1999-02-28       0.0             0.0               0.0          0.0         0.0
# 1999-03-31       0.0             0.0               0.0          0.0         0.0
# 1999-04-30       0.0             0.0               0.0          0.0         0.0
# 1999-05-31       0.0             0.0               0.0          0.0         0.0
# 1999-06-30       0.0             0.0               0.0          0.0         0.0
# 1999-07-31       0.0             0.0               0.0          0.0         0.0
# 1999-08-31       0.0             0.0               0.0          0.0         0.0
# 1999-09-30       0.0             0.0               0.0          0.0         0.0
# 1999-10-31       0.0             0.0               0.0          0.0         0.0
# 1999-11-30       0.0             0.0               0.0          0.0         0.0
# 1999-12-31       0.0             0.0               0.0          0.0         0.0
# 2000-01-31       0.0             0.0               0.0          4.0         1.0