DataFrame

Playing Pandas

Die grundlegende Idee von DataFrame basiert auf Tabellen. Wir können die Daten-Struktur eines DataFrame als tabellarisch und tabellenähnlich sehen. Es beinhaltet eine geordnete Sammlung von Spalten. Jede Spalte besteht aus einem eindeutigen Daten-Typen, aber verschiedene Spalten haben verschiedene Typen, z.B. hat die erste Spalte den Typ Integer, während die zweite Spalte vom Typ Boolean ist, usw.

Ein DataFrame hat einen Zeilen- und ein Spalten-Index. Es ist wie ein Dictionary aus Series mit einem normalen Index. Wir demonstrieren dies im folgenden Beispiel, in dem drei Series-Objekte definiert werden:

import pandas as pd
years = range(2014, 2018)
shop1 = pd.Series([2409.14, 2941.01, 3496.83, 3119.55], index=years)
shop2 = pd.Series([1203.45, 3441.62, 3007.83, 3619.53], index=years)
shop3 = pd.Series([3412.12, 3491.16, 3457.19, 1963.10], index=years)

Was passiert, wenn diese "shop"-Series-Objekte konkateniert werden? Pandas stellt eine concat()-Funktion für diesen Zweck zur Verfügung:

pd.concat([shop1, shop2, shop3])
Wir erhalten die folgende Ergebnisse:
2014    2409.14
2015    2941.01
2016    3496.83
2017    3119.55
2014    1203.45
2015    3441.62
2016    3007.83
2017    3619.53
2014    3412.12
2015    3491.16
2016    3457.19
2017    1963.10
dtype: float64

Das Ergebnis ist wohl nicht das, was wir erwartet haben. Der Grund dafür ist, dass concat() für den axis-Parameter 0 verwendet. Probieren wir es mit "axis=1":

shops_df = pd.concat([shop1, shop2, shop3], axis=1)
print(shops_df)
            0        1        2
2014  2409.14  1203.45  3412.12
2015  2941.01  3441.62  3491.16
2016  3496.83  3007.83  3457.19
2017  3119.55  3619.53  1963.10

Wir geben den Spalten noch Namen, um es etwas abzurunden:

cities = ["Zürich", "Winterthur", "Freiburg"]
shops_df.columns = cities 
print(shops_df)
print("------")
# Alternativ: Den Series-Objekten Namen zuweisen
shop1.name = "Zürich"
shop2.name = "Winterthur"
shop3.name = "Freiburg"
shops_df2 = pd.concat([shop1, shop2, shop3], axis=1)
print(shops_df2)
       Zürich  Winterthur  Freiburg
2014  2409.14     1203.45   3412.12
2015  2941.01     3441.62   3491.16
2016  3496.83     3007.83   3457.19
2017  3119.55     3619.53   1963.10
------
       Zürich  Winterthur  Freiburg
2014  2409.14     1203.45   3412.12
2015  2941.01     3441.62   3491.16
2016  3496.83     3007.83   3457.19
2017  3119.55     3619.53   1963.10

Soweit gut, doch von welchem Typ ist das Ergebnis?

print(type(shops_df))
<class 'pandas.core.frame.DataFrame'>

Das bedeutet, dass wir Series-Objekte durch Konkatenierung in DataFrame-Objekte wandeln können!

DataFrames aus Dictionaries

Wie schon erwähnt, hat ein DataFrame einen Spalten- und einen Zeilen-Index. Es ist wie ein Dictionary aus Series-Objekten mit einem gewöhnlichen Index.

cities = {"name": ["London", "Berlin", "Madrid", "Rome", 
                   "Paris", "Vienna", "Bucharest", "Hamburg", 
                   "Budapest", "Warsaw", "Barcelona", 
                   "Munich", "Milan"],
          "population": [8615246, 3562166, 3165235, 2874038,
                         2273305, 1805681, 1803425, 1760433,
                         1754000, 1740119, 1602386, 1493900,
                         1350680],
          "country": ["England", "Germany", "Spain", "Italy",
                      "France", "Austria", "Romania", 
                      "Germany", "Hungary", "Poland", "Spain",
                      "Germany", "Italy"]}
city_frame = pd.DataFrame(cities)
print(city_frame)
         name  population  country
0      London     8615246  England
1      Berlin     3562166  Germany
2      Madrid     3165235    Spain
3        Rome     2874038    Italy
4       Paris     2273305   France
5      Vienna     1805681  Austria
6   Bucharest     1803425  Romania
7     Hamburg     1760433  Germany
8    Budapest     1754000  Hungary
9      Warsaw     1740119   Poland
10  Barcelona     1602386    Spain
11     Munich     1493900  Germany
12      Milan     1350680    Italy

Spalten-Namen auslesen

Die Namen der Spalten können wir als Liste auslesen:

city_frame.columns.values
Führt man obigen Code aus, erhält man Folgendes:
array(['name', 'population', 'country'], dtype=object)

Beliebiger Index

Der Index (0,1,2,...) wird automatisch dem DataFrame zugewiesen. Wir können ebenfalls einen angepassten/beliebigen Index verwenden:

ordinals = ["first", "second", "third", "fourth",
            "fifth", "sixth", "seventh", "eigth",
            "ninth", "tenth", "eleventh", "twelvth",
            "thirteenth"]
city_frame = pd.DataFrame(cities, index=ordinals)
print(city_frame)
                 name  population  country
first          London     8615246  England
second         Berlin     3562166  Germany
third          Madrid     3165235    Spain
fourth           Rome     2874038    Italy
fifth           Paris     2273305   France
sixth          Vienna     1805681  Austria
seventh     Bucharest     1803425  Romania
eigth         Hamburg     1760433  Germany
ninth        Budapest     1754000  Hungary
tenth          Warsaw     1740119   Poland
eleventh    Barcelona     1602386    Spain
twelvth        Munich     1493900  Germany
thirteenth      Milan     1350680    Italy

Umsortierung der Spalten

Die Sortierung kann zum Zeitpunkt der Erstellung des DataFrame definiert und angepasst werden. Damit kann sichergestellt werden, dass wir eine definierte Sortierung der Spalten haben, wenn das DataFrame aus einem Dictionary erzeugt wird. Dictionaries sind nicht geordnet, wie Sie es im Kapitel zu Dictionaries gesehen haben. Somit können wir nicht wissen, wie die Sortierung der Spalten sein wird:

city_frame = pd.DataFrame(cities,
                          columns = ["name", 
                                     "country", 
                                     "population"],
                          index = ordinals)
print(city_frame)
                 name  country  population
first          London  England     8615246
second         Berlin  Germany     3562166
third          Madrid    Spain     3165235
fourth           Rome    Italy     2874038
fifth           Paris   France     2273305
sixth          Vienna  Austria     1805681
seventh     Bucharest  Romania     1803425
eigth         Hamburg  Germany     1760433
ninth        Budapest  Hungary     1754000
tenth          Warsaw   Poland     1740119
eleventh    Barcelona    Spain     1602386
twelvth        Munich  Germany     1493900
thirteenth      Milan    Italy     1350680

Wenn Sie jedoch die Spalten-Namen und die Sortierung eines bestehenden DataFrame-Objektes anpassen wollen?

IST DAS SO RICHTIG?

print(city_frame.reindex(["country", "name", "population"]))
           name country  population
country     NaN     NaN         NaN
name        NaN     NaN         NaN
population  NaN     NaN         NaN

Jetzt wollen wir die Spalten umbenennen. Dafür verwenden wir die DataFrame-Methode rename(). Die Methode unterstützt folgende Konventionen:

Wir benennen um folgenden Beispiel die Spalten unseres DataFrame in romanische Namen um. Den Parameter inplace setzen wir auf True, damit das DataFrame-Objekt direkt geändert wird und keine neues erzeugt wird. Per Standard ist inplace auf False gesetzt!

city_frame.rename(columns={"name":"Nume", "country":"țară", "population":"populație"},
                  inplace=True)
print(city_frame)
                 Nume     țară  populație
first          London  England    8615246
second         Berlin  Germany    3562166
third          Madrid    Spain    3165235
fourth           Rome    Italy    2874038
fifth           Paris   France    2273305
sixth          Vienna  Austria    1805681
seventh     Bucharest  Romania    1803425
eigth         Hamburg  Germany    1760433
ninth        Budapest  Hungary    1754000
tenth          Warsaw   Poland    1740119
eleventh    Barcelona    Spain    1602386
twelvth        Munich  Germany    1493900
thirteenth      Milan    Italy    1350680

Bestehende Spalte als Index im DataFrame

Wir wollen im nächsten Beispiel einen nützlicheren Index erzeugen. Dafür verwenden wir die Landesnamen als Index, d.h. die Werte aus der Liste mit dem Key "country" aus unserem cities-Dicitonary:

city_frame = pd.DataFrame(cities,
                          columns=["name", "population"],
                          index=cities["country"])
print(city_frame)
              name  population
England     London     8615246
Germany     Berlin     3562166
Spain       Madrid     3165235
Italy         Rome     2874038
France       Paris     2273305
Austria     Vienna     1805681
Romania  Bucharest     1803425
Germany    Hamburg     1760433
Hungary   Budapest     1754000
Poland      Warsaw     1740119
Spain    Barcelona     1602386
Germany     Munich     1493900
Italy        Milan     1350680

Alternativ können wir das bestehende DataFrame auch verändern. Dazu nutzen wir die Methode set_index() um eine Spalte in einen Index zu wandeln. Dabei ist zu beachten, das set_index() ein neues DataFrame zurückliefert, bei dem die gewählte Spalte als Index verwendet wird:

city_frame = pd.DataFrame(cities)
city_frame2 = city_frame.set_index("country")
print(city_frame2)
              name  population
country                       
England     London     8615246
Germany     Berlin     3562166
Spain       Madrid     3165235
Italy         Rome     2874038
France       Paris     2273305
Austria     Vienna     1805681
Romania  Bucharest     1803425
Germany    Hamburg     1760433
Hungary   Budapest     1754000
Poland      Warsaw     1740119
Spain    Barcelona     1602386
Germany     Munich     1493900
Italy        Milan     1350680

Im vorherigen Beispiel haben wir gesehen, dass die Methode set_index() ein neues DataFrame-Objekt liefert und nicht das originale Objekt verändert. Im Gegensatz dazu kann der Parameter "inplace" auf True gesetzt werden, um tatsächlich das originale Objekt zu verändern:

city_frame = pd.DataFrame(cities)
city_frame.set_index("country", inplace=True)
print(city_frame)
              name  population
country                       
England     London     8615246
Germany     Berlin     3562166
Spain       Madrid     3165235
Italy         Rome     2874038
France       Paris     2273305
Austria     Vienna     1805681
Romania  Bucharest     1803425
Germany    Hamburg     1760433
Hungary   Budapest     1754000
Poland      Warsaw     1740119
Spain    Barcelona     1602386
Germany     Munich     1493900
Italy        Milan     1350680

Label-Indizes auf den Zeilen

Bis jetzt haben wir die DataFrame-Objekt über die Spalten indiziert. Nun möchten wir demonstrieren, wie wir auf die Zeilen zugreifen können. Dazu verwenden wir die locators loc() und iloc():

city_frame = pd.DataFrame(cities, 
                          columns=("name", "population"), 
                          index=cities["country"])
print(city_frame.loc["Germany"])
            name  population
Germany   Berlin     3562166
Germany  Hamburg     1760433
Germany   Munich     1493900
print(city_frame.loc[["Germany", "France"]])
            name  population
Germany   Berlin     3562166
Germany  Hamburg     1760433
Germany   Munich     1493900
France     Paris     2273305
print(city_frame.loc[city_frame.population>2000000])
           name  population
England  London     8615246
Germany  Berlin     3562166
Spain    Madrid     3165235
Italy      Rome     2874038
France    Paris     2273305

Summen und Kumulative Summen

Wir klönnen die Summe von allen Spalten berechnen oder die Summe von ausgewählten Spalten:

print(city_frame.sum())
name          LondonBerlinMadridRomeParisViennaBucharestHamb...
population                                             33800614
dtype: object
city_frame["population"].sum()
Führt man obigen Code aus, erhält man Folgendes:
33800614

Mit cumsum() berechnen wir die kumulative Summe:

x = city_frame["population"].cumsum()
print(x)
England     8615246
Germany    12177412
Spain      15342647
Italy      18216685
France     20489990
Austria    22295671
Romania    24099096
Germany    25859529
Hungary    27613529
Poland     29353648
Spain      30956034
Germany    32449934
Italy      33800614
Name: population, dtype: int64

Zuweisung neuer Werte an die Spalten

x ist ein Series-Objekt. Die zuvor berechnete kumulative Summen kann können der population-Spalte neu zugewiesen werden:

city_frame["population"] = x
print(city_frame)
              name  population
England     London     8615246
Germany     Berlin    12177412
Spain       Madrid    15342647
Italy         Rome    18216685
France       Paris    20489990
Austria     Vienna    22295671
Romania  Bucharest    24099096
Germany    Hamburg    25859529
Hungary   Budapest    27613529
Poland      Warsaw    29353648
Spain    Barcelona    30956034
Germany     Munich    32449934
Italy        Milan    33800614

Anstelle die Werte in der population-Spalte komplett durch die kumulativen Summen zu ersetzen, wollen wir die neuen Werte als neue zusätzliche Spalte cum_population dem DataFrame anfügen.

city_frame = pd.DataFrame(cities,
                          columns=["country", 
                                   "population",
                                   "cum_population"],
                          index=cities["name"])
print(city_frame)
           country  population cum_population
London     England     8615246            NaN
Berlin     Germany     3562166            NaN
Madrid       Spain     3165235            NaN
Rome         Italy     2874038            NaN
Paris       France     2273305            NaN
Vienna     Austria     1805681            NaN
Bucharest  Romania     1803425            NaN
Hamburg    Germany     1760433            NaN
Budapest   Hungary     1754000            NaN
Warsaw      Poland     1740119            NaN
Barcelona    Spain     1602386            NaN
Munich     Germany     1493900            NaN
Milan        Italy     1350680            NaN

Die neue Spalte cum_population enthält nur NaN-Werte, weil noch keine Daten zur Verfügung gestellt wurden.

Nun weisen wir die kumulativen Summen dieser neuen Spalte zu:

city_frame["cum_population"] = city_frame["population"].cumsum()
print(city_frame)
           country  population  cum_population
London     England     8615246         8615246
Berlin     Germany     3562166        12177412
Madrid       Spain     3165235        15342647
Rome         Italy     2874038        18216685
Paris       France     2273305        20489990
Vienna     Austria     1805681        22295671
Bucharest  Romania     1803425        24099096
Hamburg    Germany     1760433        25859529
Budapest   Hungary     1754000        27613529
Warsaw      Poland     1740119        29353648
Barcelona    Spain     1602386        30956034
Munich     Germany     1493900        32449934
Milan        Italy     1350680        33800614

Bei der Erstellung eines DataFrame-Objektes aus einem Dictionary, können auch Spalten angegeben werden, die nicht im Dictionary enthalten sind. In diesem Fall werden die Werte ebenfalls auf NaN gesetzt:

city_frame = pd.DataFrame(cities,
                          columns=["country", 
                                   "area",
                                   "population"],
                          index=cities["name"])
print(city_frame)
           country area  population
London     England  NaN     8615246
Berlin     Germany  NaN     3562166
Madrid       Spain  NaN     3165235
Rome         Italy  NaN     2874038
Paris       France  NaN     2273305
Vienna     Austria  NaN     1805681
Bucharest  Romania  NaN     1803425
Hamburg    Germany  NaN     1760433
Budapest   Hungary  NaN     1754000
Warsaw      Poland  NaN     1740119
Barcelona    Spain  NaN     1602386
Munich     Germany  NaN     1493900
Milan        Italy  NaN     1350680

Neue Werte für eine Spalte

Wir können allen Elementen einer Spalte den selben Wert zuweisen:

city_frame["area"] = 1572
print(city_frame)
           country  area  population
London     England  1572     8615246
Berlin     Germany  1572     3562166
Madrid       Spain  1572     3165235
Rome         Italy  1572     2874038
Paris       France  1572     2273305
Vienna     Austria  1572     1805681
Bucharest  Romania  1572     1803425
Hamburg    Germany  1572     1760433
Budapest   Hungary  1572     1754000
Warsaw      Poland  1572     1740119
Barcelona    Spain  1572     1602386
Munich     Germany  1572     1493900
Milan        Italy  1572     1350680

In diesem Fall wäre es definitv besser die exakten area-Werte zu übergeben. Die Liste mit den neuen area-Werten muss die gleiche Länge haben, wie das DataFrame Zeilen hat.

# area in square km:
area = [1572, 891.85, 605.77, 1285, 
        105.4, 414.6, 228, 755, 
        525.2, 517, 101.9, 310.4, 
        181.8]
# area could have been designed as a list, 
# a Series, an array or a scalar   
city_frame["area"] = area
print(city_frame)
           country     area  population
London     England  1572.00     8615246
Berlin     Germany   891.85     3562166
Madrid       Spain   605.77     3165235
Rome         Italy  1285.00     2874038
Paris       France   105.40     2273305
Vienna     Austria   414.60     1805681
Bucharest  Romania   228.00     1803425
Hamburg    Germany   755.00     1760433
Budapest   Hungary   525.20     1754000
Warsaw      Poland   517.00     1740119
Barcelona    Spain   101.90     1602386
Munich     Germany   310.40     1493900
Milan        Italy   181.80     1350680

Zugriff auf die Spalten eines DataFrame

Es gibt zwei Wege um auf die Spalten eines DataFrame zuzugreifen. In beiden Fällen ist ein Series-Objekt das Ergebnis:

# in a dictionary-like way:
print(city_frame["population"])
London       8615246
Berlin       3562166
Madrid       3165235
Rome         2874038
Paris        2273305
Vienna       1805681
Bucharest    1803425
Hamburg      1760433
Budapest     1754000
Warsaw       1740119
Barcelona    1602386
Munich       1493900
Milan        1350680
Name: population, dtype: int64
# as an attribute
print(city_frame.population)
London       8615246
Berlin       3562166
Madrid       3165235
Rome         2874038
Paris        2273305
Vienna       1805681
Bucharest    1803425
Hamburg      1760433
Budapest     1754000
Warsaw       1740119
Barcelona    1602386
Munich       1493900
Milan        1350680
Name: population, dtype: int64
print(type(city_frame.population))
<class 'pandas.core.series.Series'>

Sortierung im DataFrame

Wir sortieren den Inhalt des DataFrame-Objektes anhand der area-Werte:

city_frame = city_frame.sort_values(by="area", ascending=False)
print(city_frame)
           country     area  population
London     England  1572.00     8615246
Rome         Italy  1285.00     2874038
Berlin     Germany   891.85     3562166
Hamburg    Germany   755.00     1760433
Madrid       Spain   605.77     3165235
Budapest   Hungary   525.20     1754000
Warsaw      Poland   517.00     1740119
Vienna     Austria   414.60     1805681
Munich     Germany   310.40     1493900
Bucharest  Romania   228.00     1803425
Milan        Italy   181.80     1350680
Paris       France   105.40     2273305
Barcelona    Spain   101.90     1602386

Nehmen wir an, wir haben lediglich die areas-Werte von London, Hamburg und Milan. Die areas-Werte befinden sich in einem Series-Objekt mit den korrekten Indizes. Die Zuweisung funktioniert ebenfalls:

city_frame = pd.DataFrame(cities,
                          columns=["country", 
                                   "area",
                                   "population"],
                          index=cities["name"])
some_areas = pd.Series([1572, 755, 181.8], 
                    index=['London', 'Hamburg', 'Milan'])
city_frame['area'] = some_areas
print(city_frame)
           country    area  population
London     England  1572.0     8615246
Berlin     Germany     NaN     3562166
Madrid       Spain     NaN     3165235
Rome         Italy     NaN     2874038
Paris       France     NaN     2273305
Vienna     Austria     NaN     1805681
Bucharest  Romania     NaN     1803425
Hamburg    Germany   755.0     1760433
Budapest   Hungary     NaN     1754000
Warsaw      Poland     NaN     1740119
Barcelona    Spain     NaN     1602386
Munich     Germany     NaN     1493900
Milan        Italy   181.8     1350680

Neue Spalten für bestehendes DataFrame

In vorherigen Beispielen haben wir Spalten bei der Erstellung des DataFrame hinzugefügt. Es ist jedoch oft notwendig Spalten in direkt in ein bereits bestehendes DataFrame einzufügen.

city_frame = pd.DataFrame(cities,
                          columns = ["country", 
                                     "population"],
                          index = cities["name"])
print(city_frame)
print("======")
city_frame.insert(loc = 1, 
                  column = 'area', 
                  value = area)
print(city_frame)
           country  population
London     England     8615246
Berlin     Germany     3562166
Madrid       Spain     3165235
Rome         Italy     2874038
Paris       France     2273305
Vienna     Austria     1805681
Bucharest  Romania     1803425
Hamburg    Germany     1760433
Budapest   Hungary     1754000
Warsaw      Poland     1740119
Barcelona    Spain     1602386
Munich     Germany     1493900
Milan        Italy     1350680
======
           country     area  population
London     England  1572.00     8615246
Berlin     Germany   891.85     3562166
Madrid       Spain   605.77     3165235
Rome         Italy  1285.00     2874038
Paris       France   105.40     2273305
Vienna     Austria   414.60     1805681
Bucharest  Romania   228.00     1803425
Hamburg    Germany   755.00     1760433
Budapest   Hungary   525.20     1754000
Warsaw      Poland   517.00     1740119
Barcelona    Spain   101.90     1602386
Munich     Germany   310.40     1493900
Milan        Italy   181.80     1350680

DataFrame aus eingebetteten Dictionaries

Eingebettetes Dictionaries können ebenfalls an eine DataFrame übergeben werden. Die Indizes des äusseren Dictionary entsprechen den Spalten und die inneren Schlüssel der Dictionaries entsprechen den Indizes der einzelnen Zeilen:

growth = {"Switzerland": {"2010": 3.0, "2011": 1.8, "2012": 1.1, "2013": 1.9},
          "Germany": {"2010": 4.1, "2011": 3.6, "2012":	0.4, "2013": 0.1},
          "France": {"2010":2.0,  "2011":2.1, "2012": 0.3, "2013": 0.3},
          "Greece": {"2010":-5.4, "2011":-8.9, "2012":-6.6, "2013":	-3.3},
          "Italy": {"2010":1.7, "2011":	0.6, "2012":-2.3, "2013":-1.9}
          } 
growth_frame = pd.DataFrame(growth)
print(growth_frame)
      Switzerland  Germany  France  Greece  Italy
2010          3.0      4.1     2.0    -5.4    1.7
2011          1.8      3.6     2.1    -8.9    0.6
2012          1.1      0.4     0.3    -6.6   -2.3
2013          1.9      0.1     0.3    -3.3   -1.9

Sie möchten vielleicht die Jahre als Spalten und die Länder als Zeilen? Sie können die Daten ohne Probleme tauschen (transpose):

print(growth_frame.T)
             2010  2011  2012  2013
Switzerland   3.0   1.8   1.1   1.9
Germany       4.1   3.6   0.4   0.1
France        2.0   2.1   0.3   0.3
Greece       -5.4  -8.9  -6.6  -3.3
Italy         1.7   0.6  -2.3  -1.9
growth_frame = growth_frame.T
growth_frame2 = growth_frame.reindex(["Switzerland", 
                                      "Italy", 
                                      "Germany", 
                                      "Greece"])
print(growth_frame2)
             2010  2011  2012  2013
Switzerland   3.0   1.8   1.1   1.9
Italy         1.7   0.6  -2.3  -1.9
Germany       4.1   3.6   0.4   0.1
Greece       -5.4  -8.9  -6.6  -3.3

DataFrame mit Zufallswerten füllen:

import numpy as np
names = ['Frank', 'Eve', 'Stella', 'Guido', 'Lara']
index = ["January", "February", "March",
         "April", "May", "June",
         "July", "August", "September",
         "October", "November", "December"]
df = pd.DataFrame((np.random.randn(12, 5)*1000).round(2),
                  columns = names,
                  index = index)
print(df)
             Frank      Eve   Stella    Guido     Lara
January    2257.31    -0.10  -647.70   570.43  -219.97
February  -1081.04   -26.72 -1866.20   336.54  1038.72
March      -684.98  1061.64  -647.76    80.85  -351.45
April      -276.75  -167.59 -1824.75 -1365.45  1113.01
May       -1052.50  -304.42 -1546.91 -1420.95 -1346.13
June       1937.25  1693.60   943.58   583.06   944.23
July       2360.19  -201.91   295.32    90.80   -24.41
August     2030.67 -1235.29   352.79 -1246.83 -1173.51
September   631.16  -204.20  -906.75  1104.72  1201.31
October     113.35  -208.55   979.98   949.24   739.01
November    734.76  -139.01    74.93   207.89  -377.41
December    349.10 -1578.26   147.47  1165.10  -191.92