Подсчет количества раз, когда переменная меняла значения - PullRequest
0 голосов
/ 22 января 2019

Предположим, я случайно генерирую список.

mylist = []
for i in range(0,10):
        s = np.random.choice([-1,0,1])
        mylist.append(s)

Сейчас for x in range(0,100). Я изменяю элементы в соответствии с некоторыми правилами, а затем подсчитываю количество элементов каждого типа, используя counts = Counter(mylist)

for x in range(0,100):
    #some rules
    counts = Counter[mylist]

В начале список может находиться в состоянии, когда, скажем, число -1 больше, чем число +1, и затем переходить из состояния, в котором число +1 больше, чем число -1.

Есть ли способ подсчитать, сколько раз был сделан такой переход? В дополнение к этому, будет ли возможно записать значения x, когда такой переход будет сделан в списке.

До сих пор я пытался представить эти данные в сравнении с

p = counts[1]
m = counts[-1]  
plt.plot(x, p,m)
plt.show()

и найдите точки пересечения. Есть ли лучший способ сделать это, или есть некоторые встроенные функции в Python и / или NumPy. Кроме того, было бы замечательно, если бы я мог добиться перехода в состояние с высоким +1, когда нет. +1> 1,5 (№ +1), и в состояние высокого -1, когда нет. -1> 1,5 * (номер +1). (Или некоторый другой произвольный префактор, 2, 3 и т. Д. Вместо 1 или 1,5)

Ответы [ 3 ]

0 голосов
/ 22 января 2019

Если вас интересует, какой элемент является наиболее распространенным в вашем списке, тогда Counter имеет встроенную функцию most_common(), которую вы можете запросить:

counts = Counter()
for x in range(0, 100):
    # some rules
    s = np.random.choice([-1, 0, 1])
    mylist.append(s)
    if mylist.count(1) > mylist.count(-1) and mylist.count(1) > mylist.count(0):
        counts[1] += 1
    elif mylist.count(-1) > mylist.count(1) and mylist.count(-1) > mylist.count(0):
        counts[-1] += 1
    else:
        counts[0] += 1
    print(counts.most_common())

.Наиболее распространенный элемент (вместе с его количеством) должен быть первым элементом в возвращенном списке.Вот несколько соседних возвратов вокруг точки перехода:

[(-1, 28), (0, 27), (1, 26)]
[(-1, 28), (0, 27), (1, 27)]
[(1, 28), (-1, 28), (0, 27)]   # Transition here as -1 and +1 both have a count of 28
[(1, 29), (-1, 28), (0, 27)]
0 голосов
/ 22 января 2019

Этот ответ предполагает, что вы пытаетесь подсчитать только переходы и не пытаетесь отображать значения (последний абзац вопроса).

Если вы имеете дело только с набором {-1, 0, 1}, возможно, вы можете суммировать значения из списка. Это немного быстрее, чем добавить их в счетчик и дает вам информацию о переходе.

И, конечно, проще не суммировать полный список каждый раз, а просто увеличивать / уменьшать счетчик внутри вашего логического блока, когда происходят изменения.

more_ones = True if sum(my_list) > 0 else False
transition_counter = 0
transitions_history = []
for x in range(0, 100): 
    # some rules, which change mylist
    # you can place a transition counter logic right here
    current_sum = sum(my_list)  # one more time, counting inside the logic is faster
    if current_sum < 0 and more_ones:
        transition_counter  += 1
        more_ones = False
        transitions_history.append(x)
    elif current_sum > 0 and not more_ones:  
        transition_counter  += 1
        more_ones = True
        transitions_history.append(x)

здесь я предполагаю, что если сумма не пересекает ноль, то перехода нет.

Подобный подход работает в префакторном случае (если я правильно понял идею):

my_list = [0, 1, -1, -1]  # sample data

factor = 1.5  # some factor
pos_count = my_list.count(1)
neg_count = my_list.count(-1)
more_ones = True if pos_count > factor * neg_count else False  # unclear part - don't know what you plan to do with zeroes
transition_counter = 0
transitions_history = []
for x in range(0, 100):
    # I provide a test logic
    ### CROP HERE ###
    try:
        if x < 3:
            my_list.remove(-1)  # better to decrement/increment pos. and neg. counts here
        elif x >= 3 and x < 5:
            my_list.append(1)
        elif x >= 5 and x < 10:
            my_list.append(-1)
        else:
            my_list.append(1)
    except ValueError:
        pass
    ### CROP HERE ###
    pos_count = my_list.count(1)
    neg_count = my_list.count(-1)
    if neg_count > pos_count * factor and more_ones:
        transition_counter  += 1
        more_ones = False
        # you couldn't store list and need a copy, otherwise it will change values by pointer
        transitions_history.append((x, 'pos_to_neg', [i for i in my_list]))
    elif pos_count > neg_count * factor and not more_ones:
        transition_counter += 1
        more_ones = True
        transitions_history.append((x, 'neg_to_pos', [i for i in my_list]))

Пример вывода:

transitions_history
Out:
    [(1, 'neg_to_pos', [0, 1]),
     (9, 'pos_to_neg', [0, 1, 1, 1, -1, -1, -1, -1, -1]),
     (14, 'neg_to_pos', [0, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1])]
transition_counter
Out:
3
0 голосов
/ 22 января 2019
import random

mylist = []
new_list = list(mylist)
transitions = []

for x in range(0,100): 
    mylist.append(random.choice([1, 0, -1])) # some rules, which change mylist
    is_trans1 = new_list.count(1) > new_list.count(-1) and mylist.count(1) < mylist.count(-1)
    is_trans2 = new_list.count(1) < new_list.count(-1) and mylist.count(1) > mylist.count(-1)
    if is_trans1 or is_trans2:
        transitions.append(x)       
    new_list = list(mylist) # save mylist for the next iteration
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...