Найти и подсчитать все вхождения и положение чисел в диапазоне в списке

Я хочу найти, сколько раз каждое число появляется в каждой позиции индекса в списке из 6 наборов чисел, когда я не знаю, какими будут числа, но они будут варьироваться только от 0 до 99.

Примерный список:

data = [['22', '45', '6', '72', '1', '65'], ['2', '65', '67', '23', '98', '1'], ['13', '45', '98', '4', '12', '65']]

В конце концов я буду помещать полученные подсчеты в pandas DataFrame, чтобы они выглядели примерно так:

num numofoccurances position numoftimesinposition
01         02            04            01
01         02            05            01
02         01            00            01
04         02            03            01
06         01            02            01
12         01            04            01
13         01            00            01
and so on...

Результирующие данные будут немного отличаться из-за того, что num повторяется каждый раз, когда он появляется в другой позиции индекса, но, надеюсь, это поможет вам понять, что я ищу.

Пока вот что я начал:

data = json.load(f)
numbers = []
contains = []

'''
This section is simply taking the data from the json file and putting it all into a list of lists containing the 6 elements I need in each list
'''
for i in data['data']:
    item = [i[9], i[10]]
#   print(item)
    item = [words for segments in item for words in segments.split()]
    numbers.append(item)

'''
This is my attempt to count to number of occurrences for each number in the range then add it to a list.
'''
x = range(1,99)
for i in numbers:
    if x in i and not contains:
        contains.append(x)

person JxnDistro    schedule 30.07.2020    source источник
comment
Можете ли вы описать, что представляет собой каждый из трех столбцов? первое значение 22 в numofoccurances.. это просто прямое число, которое существует в данных? А что такое число.. это 0-99? или его индекс для 6 списков длины?   -  person Akshay Sehgal    schedule 30.07.2020
comment
@AkshaySehgal num — это число, которое встречается в списке. numofoccurrences — это общее количество раз, когда это число встречается. position — это позиция индекса, в которой появилось число. numoftimesinpostion — это количество раз, когда это число встречалось в этой конкретной позиции индекса.   -  person JxnDistro    schedule 30.07.2020
comment
Не могли бы вы отредактировать таблицу, чтобы она соответствовала приведенным данным?   -  person Onyambu    schedule 30.07.2020
comment
@Onyambu пример DataFrame является произвольным. Это исключительно для понимания того, что я буду делать с данными, когда получу их. Я могу создать DataFrame, мне просто нужен способ получить данные для DataFrame.   -  person JxnDistro    schedule 30.07.2020
comment
в чем разница между numoccurance и numtimesinposition   -  person Akshay Sehgal    schedule 30.07.2020
comment
@AkshaySehgal numofoccurrences — это общее количество раз, когда это число появляется во всех наборах, тогда как numtimesinposition — это общее количество раз, когда число появляется в этой конкретной позиции индекса.   -  person JxnDistro    schedule 30.07.2020
comment
понятно! проверьте мое решение.   -  person Akshay Sehgal    schedule 30.07.2020


Ответы (2)


import pandas as pd
num_pos = [(num,pos) for i in data for pos,num in enumerate(i)]
df = pd.DataFrame(num_pos,columns = ['number','position']).assign(numoftimesinposition = 1)
df = df.astype(int).groupby(['number','position']).count().reset_index()

df1 = df.groupby('number').numoftimesinposition.sum().reset_index().\
    rename(columns = {'numoftimesinposition':'numofoccurences'}).\
    merge(df, on='number')

print(df1)
    number  numofoccurences  position  numoftimesinposition
0        1                2         4                     1
1        1                2         5                     1
4        2                1         0                     1
7        4                1         3                     1
9        6                1         2                     1
2       12                1         4                     1
3       13                1         0                     1
5       22                1         0                     1
6       23                1         3                     1
8       45                2         1                     2
10      65                3         1                     1
11      65                3         5                     2
12      67                1         2                     1
13      72                1         3                     1
14      98                2         2                     1
15      98                2         4                     1

если приведенный выше код кажется медленным, используйте Counter из collections:

import pandas as pd
from collections import Counter

num_pos = [(int(num),pos) for i in data for pos,num in enumerate(i)]

count_data = [(num,pos,occurence) for (num,pos), occurence in Counter(num_pos).items()]

df = pd.DataFrame(count_data, columns = ['num','pos','occurence']).sort_values(by='num')

df['total_occurence'] = [Counter(df.num).get(num) for num in df.num]
print(df)
person Onyambu    schedule 30.07.2020
comment
Итак, когда я запускаю это, я получаю только 3 столбца в DataFrame. номер, позиция и количество раз в позиции. Есть ли еще один шаг, который необходимо предпринять? - person JxnDistro; 30.07.2020
comment
Я получил это, но мне нравится обработка тоже. В предыдущем DataFrame не обновлялся с дополнительным столбцом. Я только что добавил df= в раздел df.groupby, и он работает. Я тоже попробую Counter и посмотрю, как пойдет. - person JxnDistro; 30.07.2020

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

#get the list of lists into a 2d numpy array
dd = np.array(data).astype(int)

#get vocab of all unique numbers
vocab = np.unique(dd.flatten())

#loop thru vocab and get sum of occurances in each index position
df = pd.DataFrame([[i]+list(np.sum((dd==i).astype(int), axis=0)) for i in vocab])

#rename cols
df.columns = ['num', 0, 1, 2, 3, 4, 5] 

#create total occurances of the item
df['numoccurances'] = df.iloc[:,1:].sum(axis=1)  
 
#Stack the position counts and rename cols
stats = pd.DataFrame(df.set_index(['num','numoccurances']).\
                     stack()).reset_index().\
                     set_axis(['num', 'numoccurances', 'position', 'numtimesinposition'], axis=1)

#get only rows with occurances
stats = stats[stats['numtimesinposition']>0].reset_index(drop=True) 
stats
    num  numoccurances  position  numtimesinposition
0     1              2         4                   1
1     1              2         5                   1
2     2              1         0                   1
3     4              1         3                   1
4     6              1         2                   1
5    12              1         4                   1
6    13              1         0                   1
7    22              1         0                   1
8    23              1         3                   1
9    45              2         1                   2
10   65              3         1                   1
11   65              3         5                   2
12   67              1         2                   1
13   72              1         3                   1
14   98              2         2                   1
15   98              2         4                   1

Как показывают результаты -

1 появляется в общей сложности 2 раза в образцах данных, которыми вы поделились, и встречается по 1 разу на 5-й и 6-й позициях. Точно так же 2 приходит всего 1 раз, и это тоже на 1-й позиции.

person Akshay Sehgal    schedule 30.07.2020
comment
Это потрясающе! Спасибо! - person JxnDistro; 30.07.2020