array - python plot title




Gruppieren Sie nach Pandas Datenrahmen und wählen Sie den häufigsten String-Faktor (4)

Das Problem share ist die Leistung, wenn Sie viele Zeilen haben, wird es ein Problem sein.

Wenn es Ihr Fall ist, versuchen Sie bitte Folgendes:

import pandas as pd

source = pd.DataFrame({'Country' : ['USA', 'USA', 'Russia','USA'], 
              'City' : ['New-York', 'New-York', 'Sankt-Petersburg', 'New-York'],
              'Short_name' : ['NY','New','Spb','NY']})

source.groupby(['Country','City']).agg(lambda x:x.value_counts().index[0])

source.groupby(['Country','City']).Short_name.value_counts().groupby['Country','City']).first()

Ich habe einen Datenrahmen mit drei String-Spalten. Ich weiß, dass der einzige Wert in der dritten Spalte für jede Kombination der ersten beiden gültig ist. Um die Daten zu bereinigen, muss ich nach Datenrahmen nach den ersten beiden Spalten gruppieren und den häufigsten Wert der dritten Spalte für jede Kombination auswählen.

Mein Code:

import pandas as pd
from scipy import stats

source = pd.DataFrame({'Country' : ['USA', 'USA', 'Russia','USA'], 
                  'City' : ['New-York', 'New-York', 'Sankt-Petersburg', 'New-York'],
                  'Short name' : ['NY','New','Spb','NY']})

print source.groupby(['Country','City']).agg(lambda x: stats.mode(x['Short name'])[0])

Die letzte Codezeile funktioniert nicht, es heißt "Schlüsselfehler 'Kurzname'" und wenn ich versuche, nur nach Stadt zu gruppieren, habe ich einen AssertionError bekommen. Was kann ich reparieren?


Ein bisschen spät zum Spiel hier, aber ich hatte Probleme mit der Lösung von HYRY, also musste ich mir eine andere überlegen.

Es funktioniert, indem die Häufigkeit jedes Schlüsselwerts gefunden wird und dann für jeden Schlüssel nur der Wert beibehalten wird, der am häufigsten angezeigt wird.

Es gibt auch eine zusätzliche Lösung, die mehrere Modi unterstützt.

Bei einem Skalentest, der die Daten darstellt, mit denen ich arbeite, wurde die Laufzeit von 37.4 auf 0.5 Sekunden reduziert!

Hier ist der Code für die Lösung, einige Beispielverwendung und der Waagentest:

import numpy as np
import pandas as pd
import random
import time

test_input = pd.DataFrame(columns=[ 'key',          'value'],
                          data=  [[ 1,              'A'    ],
                                  [ 1,              'B'    ],
                                  [ 1,              'B'    ],
                                  [ 1,              np.nan ],
                                  [ 2,              np.nan ],
                                  [ 3,              'C'    ],
                                  [ 3,              'C'    ],
                                  [ 3,              'D'    ],
                                  [ 3,              'D'    ]])

def mode(df, key_cols, value_col, count_col):
    '''                                                                                                                                                                                                                                                                                                                                                              
    Pandas does not provide a `mode` aggregation function                                                                                                                                                                                                                                                                                                            
    for its `GroupBy` objects. This function is meant to fill                                                                                                                                                                                                                                                                                                        
    that gap, though the semantics are not exactly the same.                                                                                                                                                                                                                                                                                                         

    The input is a DataFrame with the columns `key_cols`                                                                                                                                                                                                                                                                                                             
    that you would like to group on, and the column                                                                                                                                                                                                                                                                                                                  
    `value_col` for which you would like to obtain the mode.                                                                                                                                                                                                                                                                                                         

    The output is a DataFrame with a record per group that has at least one mode                                                                                                                                                                                                                                                                                     
    (null values are not counted). The `key_cols` are included as columns, `value_col`                                                                                                                                                                                                                                                                               
    contains a mode (ties are broken arbitrarily and deterministically) for each                                                                                                                                                                                                                                                                                     
    group, and `count_col` indicates how many times each mode appeared in its group.                                                                                                                                                                                                                                                                                 
    '''
    return df.groupby(key_cols + [value_col]).size() \
             .to_frame(count_col).reset_index() \
             .sort_values(count_col, ascending=False) \
             .drop_duplicates(subset=key_cols)

def modes(df, key_cols, value_col, count_col):
    '''                                                                                                                                                                                                                                                                                                                                                              
    Pandas does not provide a `mode` aggregation function                                                                                                                                                                                                                                                                                                            
    for its `GroupBy` objects. This function is meant to fill                                                                                                                                                                                                                                                                                                        
    that gap, though the semantics are not exactly the same.                                                                                                                                                                                                                                                                                                         

    The input is a DataFrame with the columns `key_cols`                                                                                                                                                                                                                                                                                                             
    that you would like to group on, and the column                                                                                                                                                                                                                                                                                                                  
    `value_col` for which you would like to obtain the modes.                                                                                                                                                                                                                                                                                                        

    The output is a DataFrame with a record per group that has at least                                                                                                                                                                                                                                                                                              
    one mode (null values are not counted). The `key_cols` are included as                                                                                                                                                                                                                                                                                           
    columns, `value_col` contains lists indicating the modes for each group,                                                                                                                                                                                                                                                                                         
    and `count_col` indicates how many times each mode appeared in its group.                                                                                                                                                                                                                                                                                        
    '''
    return df.groupby(key_cols + [value_col]).size() \
             .to_frame(count_col).reset_index() \
             .groupby(key_cols + [count_col])[value_col].unique() \
             .to_frame().reset_index() \
             .sort_values(count_col, ascending=False) \
             .drop_duplicates(subset=key_cols)

print test_input
print mode(test_input, ['key'], 'value', 'count')
print modes(test_input, ['key'], 'value', 'count')

scale_test_data = [[random.randint(1, 100000),
                    str(random.randint(123456789001, 123456789100))] for i in range(1000000)]
scale_test_input = pd.DataFrame(columns=['key', 'value'],
                                data=scale_test_data)

start = time.time()
mode(scale_test_input, ['key'], 'value', 'count')
print time.time() - start

start = time.time()
modes(scale_test_input, ['key'], 'value', 'count')
print time.time() - start

start = time.time()
scale_test_input.groupby(['key']).agg(lambda x: x.value_counts().index[0])
print time.time() - start

Wenn Sie diesen Code ausführen, wird Folgendes ausgegeben:

   key value
0    1     A
1    1     B
2    1     B
3    1   NaN
4    2   NaN
5    3     C
6    3     C
7    3     D
8    3     D
   key value  count
1    1     B      2
2    3     C      2
   key  count   value
1    1      2     [B]
2    3      2  [C, D]
0.489614009857
9.19386196136
37.4375009537

Hoffe das hilft!


Für agg erhält die Lambba-Funktion eine Series , die kein Attribut 'Short name' Kurzname 'Short name' hat.

stats.mode gibt ein Tupel von zwei Arrays zurück, so dass Sie das erste Element des ersten Arrays in diesem Tupel verwenden müssen.

Mit diesen zwei einfachen Änderungen:

source.groupby(['Country','City']).agg(lambda x: stats.mode(x)[0][0])

kehrt zurück

                         Short name
Country City                       
Russia  Sankt-Petersburg        Spb
USA     New-York                 NY

Formal ist die richtige Antwort die @eumiro-Lösung. Das Problem von @HYRY-Lösung ist, dass wenn Sie eine Folge von Zahlen wie [1,2,3,4] haben, die Lösung falsch ist, dh Sie haben den Modus nicht . Beispiel:

import pandas as pd
df = pd.DataFrame({'client' : ['A', 'B', 'A', 'B', 'B', 'C', 'A', 'D', 'D', 'E', 'E', 'E','E','E','A'], 'total' : [1, 4, 3, 2, 4, 1, 2, 3, 5, 1, 2, 2, 2, 3, 4], 'bla':[10, 40, 30, 20, 40, 10, 20, 30, 50, 10, 20, 20, 20, 30, 40]})

Wenn Sie wie @HYRY berechnen, erhalten Sie:

df.groupby(['socio']).agg(lambda x: x.value_counts().index[0])

und Sie erhalten:

Was eindeutig falsch ist (siehe den A- Wert, der 1 und nicht 4 sein sollte ), weil es mit eindeutigen Werten nicht umgehen kann.

Also ist die andere Lösung richtig:

import scipy.stats
df3.groupby(['client']).agg(lambda x: scipy.stats.mode(x)[0][0])

bekommen:







pandas