按日期和其他列值过滤Pandas df

时间:2019-05-09 04:48:53

标签: python pandas

df看起来像这样:

df.columns = ['ReportDate', 'ClientId', 'ClientRevenue']

我想获得报告收入较高的所有客户的清单,其中包括2个日期。这是一些未经测试的概述代码,但想知道是否有更直接的Pythonic方法:

enddatedf = df.loc[df['ReportDate'] == endDate]
startdatedf = df.loc[df['ReportDate'] == startDate]

endclients = enddatedf['ClientId'].unique()
startclients = startdatedf['ClientId'].unique()
commonclients = list(set(startclients).intersect(set(endclients)) #because clients might have dropped off in b/w

risingclients = []
for client in commonclients:
    startrevenue = startdatedf.loc[startdatedf['ClientId'] == client, 'ClientRevenue'].values[0]
    endrevenue = enddatedf.loc[enddatedf['ClientId'] == client, 'ClientRevenue'].values[0]
    if endrevenue > startrevenue:
    risingclients.append(client)

谢谢

2 个答案:

答案 0 :(得分:1)

创建数据。请在您的问题中提供数据。 :)

startdate = pd.datetime(2019, 1, 1)
enddate = pd.datetime(2019, 3, 31)

df = pd.DataFrame(
    data={
        "ReportDate": [startdate, enddate, startdate, enddate, startdate, enddate],
        "ClientId": [2, 1, 3, 3, 1, 2],
        "ClientRevenue": [1432, 8493, 2316, 2145, 3211, 8763],
    }
)

print(df)

  ReportDate  ClientId  ClientRevenue
0 2019-01-01         2           1432
1 2019-03-31         1           8493
2 2019-01-01         3           2316
3 2019-03-31         3           2145
4 2019-01-01         1           3211
5 2019-03-31         2           8763

第一步是为开始日期和结束日期过滤df。

df = df.loc[((df['ReportDate']==startdate) | (df['ReportDate']==enddate)),:]

接下来,对数据框进行排序,以便您可以按日期顺序将客户端连接在一起。

df = df.sort_values(['ClientId','ReportDate'])

ReportDate  ClientId  ClientRevenue
4 2019-01-01         1           3211
1 2019-03-31         1           8493
0 2019-01-01         2           1432
5 2019-03-31         2           8763
2 2019-01-01         3           2316
3 2019-03-31         3           2145

接下来,从结束日期ClientRevenue中减去开始日期ClientRevenue。如果值是正数,则客户在两个日期之间有增长。

result = df.groupby('ClientId').last() - df.groupby('ClientId').first()
print(result)

         ReportDate  ClientRevenue
ClientId                          
1           89 days           5282
2           89 days           7331
3           89 days           -171

最后,过滤结果数据帧中的'ClientRevenue'正数,并将索引('ClientId')列出。

print("ClientId with positive return: ", result[result['ClientRevenue']>0].index.tolist())
ClientId with positive return:  [1, 2]

编辑 我错过了有关客户流失的部分,但我回去进行了测试,它仍然有效。

添加ClientId = 0,但仅包含开始日期。

  ReportDate  ClientId  ClientRevenue
0 2019-01-01         0           1324
1 2019-01-01         2           1432
2 2019-03-31         1           8493
3 2019-01-01         3           2316
4 2019-03-31         3           2145
5 2019-01-01         1           3211
6 2019-03-31         2           8763

结果计算为:

         ReportDate  ClientRevenue
ClientId                          
0            0 days              0
1           89 days           5282
2           89 days           7331
3           89 days           -171

ClientId with positive return:  [1, 2]

答案 1 :(得分:0)

df = df.sort_values(['ReportDate'], ascending=[True]) #Ensure your ReportDate is datetime column
df = df[(df['ReportDate'] > startDate) & (df['date'] <= endDate)] #You can have startDate, endDate as variables at top of your code section
del df['ReportDate']
df = df.groupby(['ClientId'],as_index=False).sum()
df = df.sort_values(['ClientRevenue'], ascending=[False])
top5 = df.head(5)   #Selecting the top 5 clients