2017-06-26 2 views
3

Ist es möglich, Teile von Spalten im Pandas Dataframe zu vergleichen? Ich habe das folgende Dataframe-Beispiel, darin sind 4 Sprachen gespeichert (en, de, nl, ua) und jede Sprache soll die gleichen Schlüssel/dieselbe Anzahl an Schlüsseln haben, aber mit unterschiedlichen Werten (die statische Spalte dort belassen) zur Vervollständigung, da ich eine statische Spalte habe, deren Werte immer gleich bleiben).Wie man aggregierte Teile des Pandas Dataframe vergleicht?

static │ langs │ keys │ values 

x  │ en  │ key_1 │ value_en_1 
x  │ en  │ key_2 │ value_en_2 
x  │ en  │ key_3 │ value_en_3 
x  │ de  │ key_1 │ value_de_1 
x  │ de  │ key_2 │ value_de_2 
x  │ de  │ key_3 │ value_de_3 
x  │ nl  │ key_1 │ value_nl_1 
x  │ nl  │ key_2 │ value_nl_2 
x  │ ua  │ key_1 │ value_ua_1 

Ich muss überprüfen, was Tasten und wieviele pro Sprache im Vergleich zum englischen fehlen (‚en‘ hier), so etwas wie dies wäre eine gewünschte Ausgabe sein:

│ Lang │ Static │ # Missing │ Keys   │ 
│ de │ x  │ 0   │    │ 
│ nl │ x  │ 1   │ key_3   │ 
│ ua │ x  │ 2   │ key_2, key_3 │ 

Dies ist mein aktueller Fortschritt:

import pandas as pd 

# this is read from a csv, but I'll leave it as list of lists for simplicity 
rows = [ 
    ['x', 'en', 'key_1', 'value_en_1'], 
    ['x', 'en', 'key_2', 'value_en_2'], 
    ['x', 'en', 'key_3', 'value_en_3'], 
    ['x', 'de', 'key_1', 'value_de_1'], 
    ['x', 'de', 'key_2', 'value_de_2'], 
    ['x', 'de', 'key_3', 'value_de_3'], 
    ['x', 'nl', 'key_1', 'value_nl_1'], 
    ['x', 'nl', 'key_2', 'value_nl_2'], 
    ['x', 'ua', 'key_1', 'value_en_1'] 
] 

# create DataFrame out of rows of data 
df = pd.DataFrame(rows, columns=["static", "language", "keys", "values"]) 
# print out DataFrame 
print("Dataframe: ", df) 

# first group by language and the static column 
df_grp = df.groupby(["static", "language"]) 

# try to sum the number of keys and values per each language 
df_summ = df_grp.agg(["count"]) 

# print out the sums 
print() 
print(df_summ) 

# how to compare? 
# how to get the keys? 

Dies ist der Ausgang des df_summ ist:

    keys values 
       count count 
static language    
x  de   3  3 
     en   3  3 
     nl   2  2 
     ua   1  1 

An diesem Punkt weiß ich nicht weiter. Ich bin dankbar für jede Hilfe/Tipps.

P.S. Dies ist auf Python 3.5.

Antwort

3

EDIT:

#get set per groups by static and language 
a = df.groupby(["static",'language'])['keys'].apply(set).reset_index() 
#filter only en language per group by static and create set 
b = df[df['language'] == 'en'].groupby("static")['keys'].apply(set) 
#subtract mapped set b and join 
c = (a['static'].map(b) - a['keys']).str.join(', ').rename('Keys') 
#substract lengths 
m = (a['static'].map(b).str.len() - a['keys'].str.len()).rename('Missing') 

df = pd.concat([a[['static','language']], m, c], axis=1) 
print (df) 
    static language Missing   Keys 
0  x  de  0    
1  x  en  0    
2  x  nl  1   key_3 
3  x  ua  2 key_3, key_2 

EDIT:

Ich versuche, Änderungsdaten:

rows = [ 
    ['x', 'en', 'key_1', 'value_en_1'], 
    ['x', 'en', 'key_2', 'value_en_2'], 
    ['x', 'en', 'key_3', 'value_en_3'], 
    ['x', 'de', 'key_1', 'value_de_1'], 
    ['x', 'de', 'key_2', 'value_de_2'], 
    ['x', 'de', 'key_3', 'value_de_3'], 
    ['x', 'nl', 'key_1', 'value_nl_1'], 
    ['x', 'nl', 'key_2', 'value_nl_2'], 
    ['x', 'ua', 'key_1', 'value_en_1'], 
    ['y', 'en', 'key_1', 'value_en_1'], 
    ['y', 'en', 'key_2', 'value_en_2'], 
    ['y', 'de', 'key_4', 'value_en_3'], 
    ['y', 'de', 'key_1', 'value_de_1'], 
    ['y', 'de', 'key_2', 'value_de_2'], 
    ['y', 'de', 'key_3', 'value_de_3'], 
    ['y', 'de', 'key_5', 'value_nl_1'], 
    ['y', 'nl', 'key_2', 'value_nl_2'], 
    ['y', 'ua', 'key_1', 'value_en_1'] 
] 

# create DataFrame out of rows of data 
df = pd.DataFrame(rows, columns=["static", "language", "keys", "values"]) 
# print out DataFrame 
#print(df) 

und Ausgang:

print (df) 
    static language Missing   Keys 
0  x  de  0    
1  x  en  0    
2  x  nl  1   key_3 
3  x  ua  2 key_3, key_2 
4  y  de  -3    
5  y  en  0    
6  y  nl  1   key_1 
7  y  ua  1   key_2 

Problem für de fürist 0 statisch gibt es mehr Schlüssel als in der Sprache.

+0

Fantastisch, danke . Die zweite Lösung scheint komplizierter zu sein, gibt es irgendeinen Grund, warum ich es dem ersten vorziehen würde? –

+0

Ich denke in großen Daten kann Sekunde schneller sein, wenn nur einige fehlende Kategorien. – jezrael

+0

Danke, eine andere Frage. Wo vergleicht es die anderen Sprachen mit der englischen? Ich denke, in Ihrer Lösung, wenn die deutsche Sprache zum Beispiel mehr Schlüssel als die englische Sprache hat, wird die englische Sprache als Schlüssel fehlen, oder? –

1

Sie können zuerst die fehlende Spalte erstellen, indem Sie die Anzahl der Nans gruppieren und zählen. Erstellen Sie dann die Schlüsselspalte und fügen Sie die statische Spalte hinzu.

df2 = (
    df.groupby('langs')['keys'].apply(lambda x: x.values) 
     .apply(pd.Series) 
     .assign(Missing=lambda x: x.isnull().sum(axis=1)) 
) 

(
    df2[['Missing']].assign(static=df.static.iloc[0], 
          Keys=df2.apply(lambda x: ','.join(df2.loc['en'].loc[x.isnull()]),axis=1))  
) 

Out[44]: 
     Missing   Keys static 
langs        
de   0     x 
en   0     x 
nl   1  key_3  x 
ua   2 key_2,key_3  x 
1
# First we group with `language` and aggregate `static` with `min` (it's always the same anyway) 
# and `keys` with a lambda function that creates a `set`. 
In [2]: grouped = df.groupby('language').agg({'static': 'min', 'keys': lambda x: set(x)}) 

# Then we get the missing keys... 
In [3]: missing = (grouped['keys']['en'] - grouped['keys']) 

# ... and count them 
In [4]: missing_counts = missing.apply(len).rename('# Missing') 

# Then we join all of this together and replace the keys with a joined string. 
In [5]: grouped.drop('keys', axis=1).join(missing_counts).join(missing.apply(', '.join)).reset_index() 
Out[5]: 
    language static # Missing   keys 
0  de  x   0 
1  en  x   0 
2  nl  x   1   key_3 
3  ua  x   2 key_2, key_3 
1

Da Sie die R Tag in Frage stellen, ist hier, wie es geht mit tidyr und dplyr:

library(dplyr);library(tidyr) 
df %>% 
    complete(nesting(static, langs), keys) %>% 
    group_by(langs)%>% 
    summarise(Static=max(static), 
      Missing=sum(is.na(values)), 
      Keys=toString(keys[is.na(values)]) 
      ) 

    langs Static Missing   Keys 
    <chr> <chr> <int>  <chr> 
1 de  x  0    
2 en  x  0    
3 nl  x  1  key_3 
4 ua  x  2 key_2, key_3 

Daten

df <- read.table(text="static langs keys values 
'x' 'en' 'key_1' 'value_en_1' 
'x' 'en' 'key_2' 'value_en_2' 
'x' 'en' 'key_3' 'value_en_3' 
'x' 'de' 'key_1' 'value_de_1' 
'x' 'de' 'key_2' 'value_de_2' 
'x' 'de' 'key_3' 'value_de_3' 
'x' 'nl' 'key_1' 'value_nl_1' 
'x' 'nl' 'key_2' 'value_nl_2' 
'x' 'ua' 'key_1' 'value_en_1'",header=TRUE,stringsAsFactors = FALSE) 
+0

Danke, das ist großartig. Ich lerne auch dplyr auf der Seite und ich verstehe pandas wurde basierend auf R. gebaut –