質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

5回答

14623閲覧

条件指定した要素の連続値のカウントについて

NoPython_Nolife

総合スコア49

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2018/04/07 08:43

下記のようなarray型の要素があります。符号がプラスの値が最大何回連続したか、マイナスの値が最大何回連続したかを抽出したです。
下記の例だと、プラスは3回、マイナスが2回となるイメージです。

[0.1,0.5,0.03,-019,-0.05,0.1,0.5,-0.2]

ご教示頂けると幸いです。
どうぞよろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mkgrei

2018/04/07 13:06

0が来た場合が悩みどころですが、普通はプラスにカウントするのでしょうか。
NoPython_Nolife

2018/04/08 04:17

これは決め打ちしないといけないところですね。。今回はプラスカウントと考えております。
guest

回答5

0

ベストアンサー

とりあえず『連続した回数』を取り出す方法。

Python

1from itertools import groupby 2 3src = [0.1, 0.5, 0.03, -0.19, -0.05, 0.1, 0.5, -0.2] 4dst = [sum(1 for e in it) for _, it in groupby(src, key=lambda x: x > 0)] 5print(dst)

実行結果 Wandbox

[3, 2, 2, 1]

この中から正の値、負の値それぞれの連続する最大長を得たいの~~でしょうか?~~ですね。
それぞれmax(dst[0::2])およびmax(dst[1::2])で取得できます。
先頭の要素の正負に応じて使い分ければ良いです。

投稿2018/04/07 08:56

編集2018/04/07 09:03
LouiS0616

総合スコア35668

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NoPython_Nolife

2018/04/07 09:22 編集

早速の回答ありがとうごいます!!!できました!ただ、ご説明いただきました、 「それぞれmax(dst[0::2])およびmax(dst[1::2])で取得できます。先頭の要素の正負に応じて使い分ければ良いです。」の部分が理解できておりません。。。。これはどういった意味なのでしょうか。。。大変恐縮ですが、この点補足して頂けると幸いです。
LouiS0616

2018/04/07 09:27

dstは、『正の連続した数, 負の連続した数, 正の, 負の, ...』と並んでいるかもしれませんし、 『負の連続した数, 正の, 負の, ...』と並んでいるかもしれません。 dst[0::2]は『正の, 正の, 正の, ...』あるいは『負の, 負の, 負の...』となります。 どちらか判別するためにはdst[0]の正負を調べれば良い、ということです。
NoPython_Nolife

2018/04/07 09:38

なるほど、そういう意味だったんですね!ありがとうごいます!!!すべて即答いただいた上に、大変分かりやすくご説明頂きほんとにありがとうございます。大変勉強になり、助かりました!
hayataka2049

2018/04/07 10:28

groupbyを使うのなら、正負を1と-1に変換してsumすると、maxと-minで取り出せて好都合・・・というのはどうですか result = [sum(items) for val, items in groupby([1 if x > 0 else -1 for x in lst])]
LouiS0616

2018/04/07 10:34

ikapyさんの回答の良いところを吸い込んだ感じですね。大いにアリだと思います。
LouiS0616

2018/04/07 10:36

別解として回答されてはいかがでしょうか。
hayataka2049

2018/04/07 10:39

せっかくなのでそうしました
hayataka2049

2018/04/07 10:39

せっかくなのでそうしました
guest

0

正負を1と-1に変換しておくことで、maxと-minで取り出せるというアイデアです。

python

1>>> lst = [0.1,0.5,0.03,-0.19,-0.05,0.1,0.5,-0.2] 2>>> result = [sum(item) for val, item in groupby([1 if x > 0 else -1 for x in lst])] 3>>> max(result) 43 5>>> -min(result) 62

投稿2018/04/07 10:38

hayataka2049

総合スコア30935

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikapy

2018/04/08 01:02

よく考えたら、正だけとか負だけの場合はうまくいきませんね(私の場合もそうでした)。 ストレートにコードしてみました(.はスペースです)。なおデータがエンプティの場合の対処はしていません。 from itertools import groupby test_list = [0.1, 0.5, 0.03, 0.19, 0.05, 0.1, 0.5, 0.2] result = [sum(item) for val, item in groupby([1 if x > 0 else -1 for x in test_list])] if len(result) == 1: ....if result[0] > 0: ........plus_ans = result[0] ........minus_ans = 0 ....else: ........plus_ans = 0 ........minus_ans = -result[0] else: ....plus_ans = max(result) ....minus_ans = -min(result) print(plus_ans, minus_ans)
ikapy

2018/04/08 02:27

改良しました。 from itertools import groupby test_list = [0.1, 0.5, 0.03, 0.19, 0.05, 0.1, 0.5, 0.2] plus_result = [sum(item) for val, item in groupby([1 if x >= 0 else 0 for x in test_list])] minus_result = [sum(item) for val, item in groupby([-1 if x < 0 else 0 for x in test_list])] print(max(plus_result)) print(-min(minus_result))
hayataka2049

2018/04/08 02:47

素直に一行にまとめてみたらこうなりました。numpy使うのは反則気味かもしれませんが np.array([(lambda x:[x,0] if x > 0 else [0, -x])(sum(item)) for val, item in groupby([1 if x > 0 else -1 for x in lst])]).max(axis=0)
NoPython_Nolife

2018/04/08 04:22

細かく修正までしていただき本当にありがとうございます!大変勉強になり、また助かりました!ありがとうございます!
LouiS0616

2018/04/08 05:01 編集

> よく考えたら、正だけとか負だけの場合はうまくいきませんね resultに0を加えておくのはどうでしょう。 result = [sum(item) for val, item in groupby([1 if x > 0 else -1 for x in lst])] + [0]
ikapy

2018/04/08 05:06

なるほど。感じ入りました。それだとエンプティリストの対応にもなりますしね。
hayataka2049

2018/04/08 20:34

単純で良いですね。思いつかなかった
guest

0

すでに回答が出てますが、せっかく考えたのでこんな方法もあるということで。
同一符号の場合は、カウントアップ(ダウン)するやりかたです。

python

1test_list = [0.1, 0.5, 0.03, -0.19, -0.05, 0.1, 0.5, -0.2] 2tmp_list = [0 for i in range(len(test_list))] 3step = 0 4for i, dat in enumerate(test_list): 5 if dat > 0.0: 6 if step < 0: 7 step = 0 8 tmp_list[i] += 1 + step 9 step += 1 10 else: 11 if step > 0: 12 step = 0 13 tmp_list[i] += -1 + step 14 step += -1 15plus_counter = max(tmp_list) 16minus_counter = -min(tmp_list) 17print(plus_counter) 18print(minus_counter) 19

投稿2018/04/07 09:39

編集2018/04/07 09:48
ikapy

総合スコア1167

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LouiS0616

2018/04/07 09:44

これは思いつかなかったです。良いですね。
NoPython_Nolife

2018/04/08 04:23

このような方法もあるんですね!ありがとうございます!
guest

0

似たような回答です。

このような
正の数 → a
負の数 → b
変換を元のリストに対して行い、それを空白なしで連結して文字列に整形します。
[0.1,0.5,0.03,-0.19,-0.05,0.1,0.5,-0.2]

aaabbaab

この整形した文字列に対して、正規表現モジュールreのパターンマッチング(a+|b+)で連続した文字列を全て取り出します。
これをsortすることで連続したaの文字列のグループ、連続したbの文字列のグループに分割することができます(実際には1つのリスト)。
後は、リストのラストが負の数の最大連続数、それを除いた残りのリストの最大値が正の数の最大連続数になります。

python

1import re 2 3src = [0.1,0.5,0.03,-0.19,-0.05,0.1,0.5,-0.2] 4 5src_t = ''.join(map(lambda x: 'ab'[x < 0], src)) 6groups = re.findall('a+|b+', src_t) 7 8def seq_len_max(groups, s): 9 return len(max(filter(lambda x: s in x, groups), key=len)) 10 11seq_plus = seq_len_max(groups, 'a') 12seq_minus = seq_len_max(groups, 'b') 13 14print(seq_plus, seq_minus)

投稿2018/04/07 11:30

編集2018/04/08 02:14
arch_

総合スコア158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NoPython_Nolife

2018/04/08 04:18

こんなやり方もあったですね。非常に勉強になりました!ありがとうございます!
arch_

2018/04/08 04:26

遊びで組んだので実行時間がアレですmm
guest

0

array型がPythonのbuilt-inのarrayなのか、numpyのarrayなのかどっちでしょう。numpy.arrayを使ったほうがごちゃごちゃしたlambda式に頼らなくていいので読みやすなるような。

Python

1import numpy as np 2src = [0.1,0.5,0.03,-0.19,-0.05,0.1,0.5,-0.2] 3src = np.array(src) 4is_positive = (src > 0) 5# array([ True, True, True, False, False, True, True, False])

あとは他の方の回答にある通り、groupbyを使うのがいいかなと思います。

python

1from itertools import groupby 2max_len = 0 3for _is_positive, items in groupby(is_positive): 4 if _is_positive: 5 n = len(list(items)) 6 pos_max = n if n > pos_max else pos_max

投稿2018/04/08 06:37

tachikoma

総合スコア3601

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問