回答編集履歴
6
test
CHANGED
@@ -39,4 +39,39 @@
|
|
39
39
|
| 7 | 1004 | 444 | 600 | 2022-05-04 |
|
40
40
|
| 8 | 1002 | 333 | 500 | 2022-08-10 |
|
41
41
|
|
42
|
+
**追記**
|
42
43
|
|
44
|
+
> ここの箇所の理解ができなかったのですが、どのようなことをされているのか
|
45
|
+
|
46
|
+
以下は `groupby(['店舗コード', '会員番号', '金額_abs'])` によってグループ化されたデータフレームの一つです。このデータフレームが `apply()` に指定した `lambda` 関数の引数(`x`)に渡されることになります。
|
47
|
+
|
48
|
+
|
49
|
+
```python
|
50
|
+
index 店舗コード 会員番号 金額 取引日時 金額_abs
|
51
|
+
2 3 1001 111 200 2022-02-05 200
|
52
|
+
5 6 1001 111 200 2022-05-01 200
|
53
|
+
8 9 1001 111 -200 2022-08-11 200
|
54
|
+
```
|
55
|
+
|
56
|
+
次に、`rolling(2)` はスライドしながら2行づつまとめます。具体的には以下の様な中身になります。
|
57
|
+
|
58
|
+
```python
|
59
|
+
# rolling(2)[0]
|
60
|
+
index 店舗コード 会員番号 金額 取引日時 金額_abs
|
61
|
+
2 3 1001 111 200 2022-02-05 200
|
62
|
+
5 6 1001 111 200 2022-05-01 200
|
63
|
+
|
64
|
+
# rolling(2)[1]
|
65
|
+
index 店舗コード 会員番号 金額 取引日時 金額_abs
|
66
|
+
5 6 1001 111 200 2022-05-01 200
|
67
|
+
8 9 1001 111 -200 2022-08-11 200
|
68
|
+
```
|
69
|
+
|
70
|
+
最初に `index` の値が `3` と `6` の行、次に `6`, `9` の行になります。これをリスト内包表記で処理していきます。
|
71
|
+
|
72
|
+
```python
|
73
|
+
.apply(lambda x: [l.index for l in x.rolling(2) if len(l)==2 and l['金額'].sum()==0][:1])
|
74
|
+
```
|
75
|
+
|
76
|
+
「金額」列の合計が `0` になる(`l['金額'].sum()==0`)組み合わせを抽出して、そのインデックス(`index` 列の値ではなくデータフレームのインデックス)を返します。`[:1]` を付けているのは、合計金額が `0` になる最初の組み合わせだけを取り出すためですが、金額が全て 0 よりも大きい場合(入金データのみ)は空リストが返るので `[0]` を指定するとエラーになってしまうことを考慮しています。
|
77
|
+
|
5
test
CHANGED
@@ -26,7 +26,7 @@
|
|
26
26
|
.groupby(['店舗コード', '会員番号', '金額_abs'])\
|
27
27
|
.apply(lambda x: [l.index for l in x.rolling(2) if len(l)==2 and l['金額'].sum()==0][:1])\
|
28
28
|
.sum()
|
29
|
-
dfx = df.drop(reduce(pd.Index.union,
|
29
|
+
dfx = df.drop(reduce(pd.Index.union, idx), errors='ignore')
|
30
30
|
|
31
31
|
print(dfx)
|
32
32
|
```
|
4
test
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
df['取引日時'] = df['取引日時'].dt.date
|
24
24
|
|
25
25
|
idx = df.sort_values('取引日時').assign(金額_abs=df['金額'].abs())\
|
26
|
-
.groupby(['店舗コード', '会員番号', '金額_abs']
|
26
|
+
.groupby(['店舗コード', '会員番号', '金額_abs'])\
|
27
27
|
.apply(lambda x: [l.index for l in x.rolling(2) if len(l)==2 and l['金額'].sum()==0][:1])\
|
28
28
|
.sum()
|
29
29
|
dfx = df.drop(reduce(pd.Index.union, (i for i in idx)), errors='ignore')
|
3
test
CHANGED
@@ -5,8 +5,6 @@
|
|
5
5
|
import pandas as pd
|
6
6
|
import io
|
7
7
|
from functools import reduce
|
8
|
-
|
9
|
-
pd.set_option('display.unicode.east_asian_width', True)
|
10
8
|
|
11
9
|
csv_data = '''
|
12
10
|
index,店舗コード,会員番号,金額,取引日時
|
2
test
CHANGED
@@ -1,20 +1,44 @@
|
|
1
1
|
> index10と2、9と7を消したいです。
|
2
2
|
|
3
3
|
おそらく、10 と 2, 9 と 6 ではないかと思います。
|
4
|
+
```python
|
5
|
+
import pandas as pd
|
6
|
+
import io
|
7
|
+
from functools import reduce
|
4
8
|
|
9
|
+
pd.set_option('display.unicode.east_asian_width', True)
|
10
|
+
|
11
|
+
csv_data = '''
|
12
|
+
index,店舗コード,会員番号,金額,取引日時
|
13
|
+
1,1001,111,100,2022/1/10
|
14
|
+
2,1002,222,200,2022/1/30
|
15
|
+
3,1001,111,200,2022/2/5
|
16
|
+
4,1003,555,500,2022/3/10
|
17
|
+
5,1002,111,200,2022/4/6
|
18
|
+
6,1001,111,200,2022/5/1
|
19
|
+
7,1004,444,600,2022/5/4
|
20
|
+
8,1002,333,500,2022/8/10
|
21
|
+
9,1001,111,-200,2022/8/11
|
22
|
+
10,1002,222,-200,2022/10/1
|
5
|
-
|
23
|
+
'''
|
24
|
+
df = pd.read_csv(io.StringIO(csv_data), parse_dates=['取引日時'])
|
25
|
+
df['取引日時'] = df['取引日時'].dt.date
|
26
|
+
|
6
|
-
d
|
27
|
+
idx = df.sort_values('取引日時').assign(金額_abs=df['金額'].abs())\
|
28
|
+
.groupby(['店舗コード', '会員番号', '金額_abs'], group_keys=False)\
|
7
|
-
.apply(lambda x:
|
29
|
+
.apply(lambda x: [l.index for l in x.rolling(2) if len(l)==2 and l['金額'].sum()==0][:1])\
|
30
|
+
.sum()
|
8
|
-
|
31
|
+
dfx = df.drop(reduce(pd.Index.union, (i for i in idx)), errors='ignore')
|
9
32
|
|
10
33
|
print(dfx)
|
11
34
|
```
|
12
35
|
| index | 店舗コード | 会員番号 | 金額 | 取引日時 |
|
13
|
-
|--------:|-------------:|-----------:|-------:|:----------
|
36
|
+
|--------:|-------------:|-----------:|-------:|:----------:|
|
14
|
-
| 1 | 1001 | 111 | 100 | 2022
|
37
|
+
| 1 | 1001 | 111 | 100 | 2022-01-10 |
|
15
|
-
| 3 | 1001 | 111 | 200 | 2022
|
38
|
+
| 3 | 1001 | 111 | 200 | 2022-02-05 |
|
16
|
-
| 4 | 1003 | 555 | 500 | 2022
|
39
|
+
| 4 | 1003 | 555 | 500 | 2022-03-10 |
|
17
|
-
| 5 | 1002 | 111 | 200 | 2022
|
40
|
+
| 5 | 1002 | 111 | 200 | 2022-04-06 |
|
18
|
-
| 7 | 1004 | 444 | 600 | 2022
|
41
|
+
| 7 | 1004 | 444 | 600 | 2022-05-04 |
|
19
|
-
| 8 | 1002 | 333 | 500 | 2022
|
42
|
+
| 8 | 1002 | 333 | 500 | 2022-08-10 |
|
20
43
|
|
44
|
+
|
1
test
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
おそらく、10 と 2, 9 と 6 ではないかと思います。
|
4
4
|
|
5
5
|
```python
|
6
|
-
dfx = df.sort_values('取引日時').groupby(['店舗コード', '会員番号']
|
6
|
+
dfx = df.sort_values('取引日時').groupby(['店舗コード', '会員番号'])\
|
7
7
|
.apply(lambda x: x[(x['金額']+x['金額'].shift()).ne(0)&(x['金額']+x['金額'].shift(-1)).ne(0)])\
|
8
8
|
.sort_values('index').reset_index(drop=True)
|
9
9
|
|