2017-05-09 117 views
1

我的问题有点类似于this one,但并不完全。我有以下类型的结构当尝试删除重复项时,熊猫只删除某些列值

| id | entrydate | sales | purchases | 
| -- | -----------| ----- | --------- | 
| 1 | 05/03/2017 | 10 | 1   | 
| 2 | 05/03/2017 | 20 | 2   | 
| 3 | 05/03/2017 | 30 | 3   | 
| 1 | 05/03/2017 | 40 | 1   | 

我读入数据帧此的CSV,和我想要得到销售和购买的每日汇总(个人ID无所谓,只是每日汇总)。

首先,我需要删除重复项。这使我绊倒了,因为如果你拿上面的例子,对于id 1,同一天有两个条目,但purchases列中的多个条目被认为是重复的,而sales列中的多个条目是有效的,所以正确的分组会导致

| id | entrydate | sales | purchases | 
| -- | -----------| ----- | --------- | 
| 1 | 05/03/2017 | 50 | 1   | 
| 2 | 05/03/2017 | 20 | 2   | 
| 3 | 05/03/2017 | 30 | 3   | 

,然后让每天的总能给我

|entrydate | sales | purchases | 
| -----------| ----- | --------- | 
| 05/03/2017 | 100 | 6   | 

我试图删除使用

purchases重复
df = pandas.read_csv('../my-csv.csv', parse_dates=True, dayfirst=True, usecols=my_columns, dtype=my_dtypes).rename(columns=str.lower).assign(date=lambda x: pd.to_datetime(x['entrydate'], format="%d/%m/%Y")).set_index('date') 

enter image description here

df = df.drop_duplicates(['id', 'entrydate', 'purchases']) 
df.drop(['id'], axis=1, inplace=True) 
df = df.groupby(pd.TimeGrouper(freq='D')).sum() 

但同时这将删除重复purchases它也除去有效sales

enter image description here


图片用于通过A-ZA-z中的溶液

enter image description here

回答

1

您可以使用GROUPBY两次,第一次以总销售

df.sales = df.groupby('id').sales.transform('sum') 
df = df.drop_duplicates() 
df.groupby(df.entrydate).sum().reset_index() 


    entrydate sales purchases 
0 2017-05-03 100  6 

编辑:为了说明和在不同日期

df.sales = df.groupby(['id', 'date']).sales.transform('sum') 
df = df.drop_duplicates() 
df.groupby('date')['sales', 'purchases'].sum().reset_index() 

你得到

date  sales purchases 
0 2017-03-05 100  6 
1 2017-03-06 40  1 
+0

这几乎适用于我,除非在csv中存在另一个日期,所以假设我在'1,06/03/2017,40,1'这样的csv中有一行,它似乎将该id的所有日期的销售额相加,然后使用该日期所有日期的值。请参阅 –

+1

pl的更新屏幕截图,以查看编辑 – Vaishali

1

如果GROUPBY entrydate你可以聚合的销售和采购:

In [11]: df.groupby("entrydate").agg({"sales": "sum", "purchases": "sum"}) 
Out[11]: 
      sales purchases 
entrydate 
05/03/2017 100   7 
+0

对不起,也许我需要整理我的问题。我想总结销售额,但对于购买,我首先要删除每个ID的重复条目,然后总和。因此,销售总额将确实总计为100,但购买将是6(因为每个日期每个ID只有一个条目计数) –

+0

@ PhilipO'Brien为什么它应该选择40到30?还是应该采取两个? –

+0

它应该从销售栏中获得(总和),但只从采购栏中获取一笔(每日采购额总是相同的,因此采用哪一张并不重要) –

0

设置

df = pd.DataFrame({'entrydate': {0: '05/03/2017', 
    1: '05/03/2017', 
    2: '05/03/2017', 
    3: '05/03/2017', 
    4: '06/03/2017', 
    5: '06/03/2017', 
    6: '06/03/2017', 
    7: '06/03/2017'}, 
'id': {0: 1, 1: 2, 2: 3, 3: 1, 4: 1, 5: 2, 6: 3, 7: 1}, 
'purchases': {0: 1, 1: 2, 2: 3, 3: 1, 4: 1, 5: 2, 6: 3, 7: 1}, 
'sales': {0: 10, 1: 20, 2: 30, 3: 40, 4: 10, 5: 20, 6: 30, 7: 40}}) 

解决方案

#First group by entrydate and id, summing sales and take the max from purchases(removing duplicates). Then another group by to sum sales and purchases. 
df.groupby(['entrydate','id']).agg({'sales':sum, 'purchases':max}).groupby(level=0).sum().reset_index() 
Out[431]: 
    entrydate purchases sales 
0 05/03/2017   6 100 
1 06/03/2017   6 100