Создание условного groupby (). Count Pandas DataFrame Where Cells <> 0 для создания частоты - PullRequest
0 голосов
/ 22 июня 2019

У меня есть датафрейм, который показывает сумму каждой комиссии, взимаемой с товара.Фрейм данных составляет около 10 миллионов строк.Я хотел бы создать новый фрейм данных, который является счетчиком каждого элемента в каждом столбце, если значение не равно нулю.

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

      Item   Fee1    Fee2    Fee3  Fee4  Fee5   Fee6  Fee7  Fee8  Fee9  Fee10  
0    10520      0     -25    -500     0   -50    -67   -99     0   -10     -5   
1    11111    -25       0     -55    -5   -20    -15  -201   -15   -50    -15   
2    85558   -100      -2       0   -35     0      0     0     0     0      0   
3    99999      0       0       0     0     0      0     0     0     0      0   
4    10000   -105       0       0     0     0     -4   -41     0     0      0   
5    66666      0       0       0     0     0      0     0     0     0      0   
6    88888     -5      -5      -4    -5    -3     -5     0    -1    -2      0   
7   125651     -1       0       0     0     0      0     0     0     0      0   
8   678923      0       0       0     0     0   -564     0     0     0      0   
9    10520     -1     -20   -2105     0     0      0     0     0     0      0   
10   11111      0      -5       0    -3     0    -15     0  -516  -351   -684   
11   85558   -151    -561       0  -516  -561 -31554 -5646 -5468 -3546   -684   
12   99999      0       0       0     0     0      0     0     0     0      0   
13   10000      0   -9681    -651  -654  -651   -651  -561  -561  -651   -561   
14   66666      0       0       0     0     0      0  -644   -65   -65    -65   
15   88888 -11651 -651615    -684     0     0      0     0     0     0      0   
16  125651 -84941  -68481 -685464 -6846   -84   -684   -11   -51     0   -888   
17  678923      0       0       0     0     0      0     0     0     0      0   

    Fee11  Fee12  Fee13  
0     -67      0      0  
1     -50      0      0  
2       0      0      0  
3       0      0   -900  
4       0      0      0  
5       0      0      0  
6      -8     -3  -7777  
7       0      0  -8888  
8       0 -85161      0  
9       0      0      0  
10   -654    -64      0  
11   -654   -654   -654  
12      0      0    -22  
13   -561   -561   -651  
14    -65    -65      0  
15      0      0      0  
16 -87984   -894      0  
17      0      0      0  

Я ищу результат, подобный приведенному ниже.

     Item  Fee1  Fee2  Fee3  Fee4  Fee5  Fee6  Fee7  Fee8  Fee9  Fee10  Fee11  
0   10520     1     2     2     0     1     1     1     0     1      1      1   
1   11111     1     1     1     2     1     2     1     2     2      2      2   
2   85558     2     2     0     2     1     1     1     1     1      1      1   
3   99999     0     0     0     0     0     0     0     0     0      0      0   
4   10000     1     1     1     1     1     2     2     1     1      1      1   
5   66666     0     0     0     0     0     0     1     1     1      1      1   
6   88888     2     2     2     1     1     1     0     1     1      0      1   
7  125651     2     1     1     1     1     1     1     1     0      1      1   
8  678923     0     0     0     0     0     1     0     0     0      0      0   

   Fee12  Fee13  
0      0      0  
1      1      0  
2      1      1  
3      0      2  
4      1      1  
5      1      0  
6      1      1  
7      1      1  
8      1      0  

Я уже пробовал приведенный ниже код, и он не заканчивается.Я позволил ему работать в течение часа, а затем убил сценарий.

dfcounted = df.groupby('Item')['Fee1', 'Fee2', 'Fee3', 'Fee4', 'Fee5', 'Fee6', 'Fee7', 'Fee8', 'Fee9', 
               'Fee10', 'Fee11', 'Fee12', 'Fee13'].agg({'Fee1': lambda x: (x<0).count(), 
               'Fee2': lambda x: (x<0).count(), 'Fee3': lambda x: (x<0).count(), 
               'Fee4': lambda x: (x<0).count(), 'Fee5': lambda x: (x<0).count(), 
               'Fee6': lambda x: (x<0).count(), 'Fee7': lambda x: (x<0).count(), 
               'Fee8': lambda x: (x<0).count(), 'Fee9': lambda x: (x<0).count(), 
               'Fee10': lambda x: (x<0).count(), 'Fee11': lambda x: (x<0).count(),
               'Fee12': lambda x: (x<0).count(), 'Fee13': lambda x: (x<0).count()})

Однако с этими примерами данных он вернул приведенный ниже кадр данных.Я также попытался переключить счетчик на сумму, и я получил кадр данных со всеми нулями.

        Fee1  Fee2  Fee3  Fee4  Fee5  Fee6  Fee7  Fee8  Fee9  Fee10  Fee11  
Item                                                                         
10000      2     2     2     2     2     2     2     2     2      2      2   
10520      2     2     2     2     2     2     2     2     2      2      2   
11111      2     2     2     2     2     2     2     2     2      2      2   
66666      2     2     2     2     2     2     2     2     2      2      2   
85558      2     2     2     2     2     2     2     2     2      2      2   
88888      2     2     2     2     2     2     2     2     2      2      2   
99999      2     2     2     2     2     2     2     2     2      2      2   
125651     2     2     2     2     2     2     2     2     2      2      2   
678923     2     2     2     2     2     2     2     2     2      2      2   

        Fee12  Fee13  
Item                  
10000       2      2  
10520       2      2  
11111       2      2  
66666       2      2  
85558       2      2  
88888       2      2  
99999       2      2  
125651      2      2  
678923      2      2  

Я новичок в Пандах и хотел бы помочь.Размер файла будет увеличиваться по мере того, как год будет продолжаться по мере добавления к каждому месяцу.

Я не уверен, что еще попробовать, поскольку мне нужна частота зарядов, чтобы помочь найти образец.

Заранее спасибо.

1 Ответ

0 голосов
/ 22 июня 2019

Вы можете упростить ваш groupby следующим образом:

df.groupby('Item').apply(lambda x: (x < 0).sum()).drop('Item', 1)

output:
        Fee1    Fee2    Fee3    Fee4    Fee5    Fee6    Fee7    Fee8    Fee9    Fee10
Item                                        
10000   1   1   1   1   1   2   2   1   1   1
10520   1   2   2   0   1   1   1   0   1   1
11111   1   1   1   2   1   2   1   2   2   2
66666   0   0   0   0   0   0   1   1   1   1
85558   2   2   0   2   1   1   1   1   1   1
88888   2   2   2   1   1   1   0   1   1   0
99999   0   0   0   0   0   0   0   0   0   0
125651  2   1   1   1   1   1   1   1   0   1
678923  0   0   0   0   0   1   0   0   0   0

Редактировать

Для оптимизации мы можем преобразовать DF в логические значения (True, если значение меньше нуля), а затем применить groupby

coluns = [colum for colum in df.columns if 'Fee' in colum]
df[coluns] = df[coluns].lt(0)
df.groupby('Item').sum()

Тест производительности с использованием timeit

%timeit df.groupby('Item').apply(lambda x: (x < 0).sum())

5,91 мс ± 115 мкс на цикл (среднее ± стандартное отклонение из 7 циклов, по 100 циклов в каждом)

Используя новый способ:

%timeit df.groupby('Item').sum()

1,25 мс ± 53,1 мкс на цикл (среднее ± стандартное отклонение из 7 циклов, 1000 циклов в каждом)

...