在Pandas数据框中,如何选择与给定的年和月匹配的所有行

时间:2018-08-19 16:36:52

标签: python pandas dataframe

我有以下示例数据:

       U_ID     Group  Location      Hours        Date
79     149        17      USA           2       2014-11-03
80     149        17      USA           2       2014-11-07
81     149        21      USA           3       2014-12-21
82     149        18      UK           1.5      2014-11-14
83     149        19      Spain         2       2014-11-21

我希望对组和位置相同的同月的小时数进行求和:

79     149        17      USA           2       2014-11-03
80     149        17      USA           2       2014-11-07

将在新数据框中变为以下内容:

1      149        17      USA          4       2014-11-01

除了可以最有效地选择与给定年份和月份匹配的数据的方式之外,我可以解决其中的大部分问题,因此在此示例中,我将如何选择2014年11月的所有内容?

我打算逐行遍历帧,然后跟踪已处理的行(因此我不会创建重复项):

def process_ids(s_df):     已处理ID = pd.DataFrame(columns = ['U_ID'],dtype ='str')

for i, row in s_df.iterrows():
    if processed_ids['U_ID'].str.contains(row['U_ID']).any():
        continue
    else:
        processed_ids = processed_ids.append({"U_ID": str(row['U_ID'])}, ignore_index=True)

我现在只需要按年份和月份进行过滤,然后检查它们是否具有相同的组和位置

1 个答案:

答案 0 :(得分:1)

groupbyGrouper汇总在一起使用,以按月MS开始分组:

df1 = (df.groupby(['U_ID', 'Group', 'Location',pd.Grouper(key='Date', freq='MS')])['Hours']
         .sum()
         .reset_index())
print (df1)
   U_ID  Group Location       Date  Hours
0   149     17      USA 2014-11-01    4.0
1   149     18       UK 2014-11-01    1.5
2   149     19    Spain 2014-11-01    2.0
3   149     21      USA 2014-12-01    3.0

然后通过boolean indexing选择:

print (df1[df1['Date'] == '2014-11-01'])
   U_ID  Group Location       Date  Hours
0   149     17      USA 2014-11-01    4.0
1   149     18       UK 2014-11-01    1.5
2   149     19    Spain 2014-11-01    2.0

print (df1[df1['Date'] == '2014-12-01'])
   U_ID  Group Location       Date  Hours
3   149     21      USA 2014-12-01    3.0

如果可能要按datetime进行选择,可以对DatetimeIndex进行一些更改:

df1 = (df.groupby(['U_ID', 'Group', 'Location',pd.Grouper(key='Date', freq='MS')])['Hours']
         .sum()
         .reset_index(level=[0,1,2]))
print (df1)
            U_ID  Group Location  Hours
Date                                   
2014-11-01   149     17      USA    4.0
2014-11-01   149     18       UK    1.5
2014-11-01   149     19    Spain    2.0
2014-12-01   149     21      USA    3.0

然后按partial string indexing进行选择:

print (df1['2014-11'])
            U_ID  Group Location  Hours
Date                                   
2014-11-01   149     17      USA    4.0
2014-11-01   149     18       UK    1.5
2014-11-01   149     19    Spain    2.0

print (df1['2014-12'])
            U_ID  Group Location  Hours
Date                                   
2014-12-01   149     21      USA    3.0

编辑:

如果还希望为非聚合组保留原始Date,则一种可能的解决方案是为size添加计数组聚合字典并聚合first,最后用{ {3}}仅一个行组,长度为1:

df1 = (df.groupby(['U_ID', 'Group', 'Location', pd.Grouper(key='Date', freq='MS')])
             .agg({'Hours':'sum', 'U_ID':'size','Date':'first'})
             .rename(columns={'Date':'processed date','U_ID':'len group'})
             .reset_index()
             )

df1['processed date'] = np.where(df1['len group'].eq(1), df1['processed date'], df1['Date'])

print (df1)
   U_ID  Group Location       Date  Hours  len group processed date
0   149     17      USA 2014-11-01    4.0          2     2014-11-01
1   149     18       UK 2014-11-01    1.5          1     2014-11-14
2   149     19    Spain 2014-11-01    2.0          1     2014-11-21
3   149     21      USA 2014-12-01    3.0          1     2014-12-21