2017-05-09 3 views
1

私の質問はthis oneと幾分似ていますが、それほどよくありません。私は、データフレームにこれを読んでいる、と私は売買の毎日集計(個人IDは関係ありません、ただ毎日集計)を取得したい構造の以下のようなものパンダは重複を削除しようとしたときに特定の列の値のみを削除します

| 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 1の場合、同じ日に2つのエントリがありますが、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') 

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

enter image description hereが、これは、重複purchasesを削除する一方、それはまた、-ZA-Zによって溶液のために有効なsales

enter image description here


画像を削除し

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 

EDIT:異なるにわたり合計を考慮するために、日付

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

あなたが売買の両方を集約することができますENTRYDATE GROUPBY場合:

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ごとに日付ごとに1つのエントリとして)である –

+0

@ PhilipO'Brienなぜ30を超えて40を選ぶべきか?または両方を取る必要がありますか? –

+0

これは、売上列から両方を取る必要がありますが、購入列から1つだけ取る必要があります(購入の日々の入力は常に同じなので、どちらを取るかは関係ありません) –

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 
関連する問題