回答編集履歴

6

2023/02/19 10:25

投稿

melian
melian

スコア19825

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

2023/02/17 18:13

投稿

melian
melian

スコア19825

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, (i for i in idx)), errors='ignore')
29
+ dfx = df.drop(reduce(pd.Index.union, idx), errors='ignore')
30
30
 
31
31
  print(dfx)
32
32
  ```

4

2023/02/17 18:03

投稿

melian
melian

スコア19825

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'], group_keys=False)\
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

2023/02/17 17:56

投稿

melian
melian

スコア19825

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

2023/02/17 17:55

投稿

melian
melian

スコア19825

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
- ```python
23
+ '''
24
+ df = pd.read_csv(io.StringIO(csv_data), parse_dates=['取引日時'])
25
+ df['取引日時'] = df['取引日時'].dt.date
26
+
6
- dfx = df.sort_values('取引日時').groupby(['店舗コード', '会員番号'])\
27
+ idx = df.sort_values('取引日時').assign(金額_abs=df['金額'].abs())\
28
+ .groupby(['店舗コード', '会員番号', '金額_abs'], group_keys=False)\
7
- .apply(lambda x: x[(x['金額']+x['金額'].shift()).ne(0)&(x['金額']+x['金額'].shift(-1)).ne(0)])\
29
+ .apply(lambda x: [l.index for l in x.rolling(2) if len(l)==2 and l['金額'].sum()==0][:1])\
30
+ .sum()
8
- .sort_values('index').reset_index(drop=True)
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/1/10 |
37
+ | 1 | 1001 | 111 | 100 | 2022-01-10 |
15
- | 3 | 1001 | 111 | 200 | 2022/2/5 |
38
+ | 3 | 1001 | 111 | 200 | 2022-02-05 |
16
- | 4 | 1003 | 555 | 500 | 2022/3/10 |
39
+ | 4 | 1003 | 555 | 500 | 2022-03-10 |
17
- | 5 | 1002 | 111 | 200 | 2022/4/6 |
40
+ | 5 | 1002 | 111 | 200 | 2022-04-06 |
18
- | 7 | 1004 | 444 | 600 | 2022/5/4 |
41
+ | 7 | 1004 | 444 | 600 | 2022-05-04 |
19
- | 8 | 1002 | 333 | 500 | 2022/8/10 |
42
+ | 8 | 1002 | 333 | 500 | 2022-08-10 |
20
43
 
44
+

1

2023/02/17 14:14

投稿

melian
melian

スコア19825

test CHANGED
@@ -3,7 +3,7 @@
3
3
  おそらく、10 と 2, 9 と 6 ではないかと思います。
4
4
 
5
5
  ```python
6
- dfx = df.sort_values('取引日時').groupby(['店舗コード', '会員番号'], group_keys=False)\
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